@telus-uds/components-web 3.2.1 → 3.3.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.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,29 @@
1
1
  # Change Log - @telus-uds/components-web
2
2
 
3
- This log was last generated on Thu, 19 Dec 2024 04:54:39 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 10 Jan 2025 21:41:25 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.3.0
8
+
9
+ Fri, 10 Jan 2025 21:41:25 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - "Search: iconLeftGap value added in the testTheme file for TextInput in Search" (35577399+JoshHC@users.noreply.github.com)
14
+ - `Docs`: fixed camelcase and hardcoded path for components (kristina.kirpichnikova@telus.com)
15
+ - `DatePicker`: update component to enable custom date formats (eduardo.pereira1@telus.com)
16
+ - `PriceLockup`: new tokens `centsPaddingTop` and `currencySymbolPaddingTop` added to the component to match with Koodo design in the micro variant (35577399+JoshHC@users.noreply.github.com)
17
+ - Bump @telus-uds/components-base to v2.4.0
18
+ - Bump @telus-uds/system-theme-tokens to v3.3.0
19
+
20
+ ### Patches
21
+
22
+ - "`DatePicker`: calendar position issue rendered incorrectly fixed" (35577399+JoshHC@users.noreply.github.com)
23
+
7
24
  ## 3.2.1
8
25
 
9
- Thu, 19 Dec 2024 04:54:39 GMT
26
+ Thu, 19 Dec 2024 05:02:20 GMT
10
27
 
11
28
  ### Patches
12
29
 
@@ -14,8 +14,6 @@ const {
14
14
  styled
15
15
  } = styledComponents;
16
16
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
17
- const dateFormat = 'DD / MM / YYYY';
18
- const dateFormatWithoutSpaces = 'DD/MM/YYYY';
19
17
  const getResponsiveDaySize = function () {
20
18
  let inline = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
21
19
  let viewport = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'md';
@@ -55,7 +53,6 @@ const PortalPositionedContainer = styled.div({
55
53
  return `${top}px`;
56
54
  }
57
55
  });
58
- const validDatePattern = /^([0-2][0-9]|3[0-1])(\/)(0[1-9]|1[0-2])\2(\d{4})$/;
59
56
  const getInitialVisibleMonth = (initialVisibleMonth, inputDate) => {
60
57
  if (initialVisibleMonth === '' || inputDate instanceof moment) {
61
58
  return null;
@@ -90,6 +87,7 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
90
87
  copy = 'en',
91
88
  id,
92
89
  date,
90
+ dateFormat = 'DD / MM / YYYY',
93
91
  feedback,
94
92
  inline = false,
95
93
  isDayDisabled,
@@ -104,12 +102,13 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
104
102
  disabled = false,
105
103
  prevTestID = '',
106
104
  nextTestID = '',
107
- placeholder = 'DD / MM / YYYY',
105
+ placeholder = dateFormat,
108
106
  initialVisibleMonth = '',
109
107
  ...rest
110
108
  } = _ref3;
111
109
  const [inputDate, setInputDate] = React.useState(date instanceof moment ? date : undefined);
112
110
  const [inputText, setInputText] = React.useState(date instanceof moment ? date.format(dateFormat) : '');
111
+ const dateFormatWithoutSpaces = dateFormat.replace(/\s/g, '');
113
112
  const textInputRef = React.useRef();
114
113
  const prevButtonRef = React.useRef();
115
114
  const [datePickerPosition, setDatePickerPosition] = React.useState({
@@ -136,7 +135,7 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
136
135
  });
137
136
 
138
137
  // Initial call to set the position
139
- updateDatePickerPosition();
138
+ throttledUpdate();
140
139
 
141
140
  // Register event listeners
142
141
  window.addEventListener('resize', throttledUpdate);
@@ -165,7 +164,7 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
165
164
  setInputDate(date);
166
165
  setInputText(date instanceof moment ? date.format(dateFormat) : '');
167
166
  }
168
- }, [date, inputDate]);
167
+ }, [date, inputDate, dateFormat]);
169
168
  React.useEffect(() => {
170
169
  let timeoutId;
171
170
  if (prevButtonRef.current && isFocused) {
@@ -234,7 +233,9 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
234
233
  }
235
234
  };
236
235
  const handleValidation = inputValidation => {
237
- if (validDatePattern.test(inputText.replace(/\s+/g, '')) === false && inputText !== '') {
236
+ const momentDate = moment(inputText, dateFormat, true);
237
+ const isValidDate = momentDate.isValid();
238
+ if (!isValidDate && inputText !== '') {
238
239
  return 'error';
239
240
  }
240
241
  if (inputValidation === 'error' || inputValidation === 'success') {
@@ -443,8 +444,11 @@ DatePicker.propTypes = {
443
444
  */
444
445
  date: momentPropTypes.momentObj,
445
446
  /**
446
- * A detailed description of validation error/success or additional instructions.
447
- * Visual variant is determined based on the `validation` prop.
447
+ * A Moment instance representing the currently selected date, i.e. `moment()`
448
+ */
449
+ dateFormat: PropTypes.string,
450
+ /**
451
+ * Optional date format for the date input. If not set, the default value will be `DD / MM / YYYY`
448
452
  */
449
453
  feedback: PropTypes.string,
450
454
  /**
@@ -499,7 +503,7 @@ DatePicker.propTypes = {
499
503
  */
500
504
  nextTestID: PropTypes.string,
501
505
  /**
502
- * Optional placeholder for the date input. If not set the default value will be `DD / MM / YYYY`
506
+ * Optional placeholder for the date input. If not set, the default value will be equal to the `dateFormat` prop
503
507
  */
504
508
  placeholder: PropTypes.string,
505
509
  /**
@@ -117,13 +117,22 @@ const StrikeThroughContainer = styled.div`
117
117
  position: absolute;
118
118
  }
119
119
  `;
120
- const selectFootnoteLinkStyles = _ref13 => {
120
+ const TypographyContainer = styled.div`
121
+ display: flex;
122
+ padding-top: ${_ref13 => {
123
+ let {
124
+ paddingTop
125
+ } = _ref13;
126
+ return `${paddingTop || 0}px`;
127
+ }};
128
+ `;
129
+ const selectFootnoteLinkStyles = _ref14 => {
121
130
  let {
122
131
  footnoteLinkColor,
123
132
  footnoteLinkFontName,
124
133
  footnoteLinkFontWeight,
125
134
  footnoteLinkLineHeight
126
- } = _ref13;
135
+ } = _ref14;
127
136
  return {
128
137
  color: footnoteLinkColor,
129
138
  fontName: footnoteLinkFontName,
@@ -131,19 +140,19 @@ const selectFootnoteLinkStyles = _ref13 => {
131
140
  lineHeight: footnoteLinkLineHeight
132
141
  };
133
142
  };
134
- const selectStrikeThroughTokens = _ref14 => {
143
+ const selectStrikeThroughTokens = _ref15 => {
135
144
  let {
136
145
  strikeThroughPosition,
137
146
  strikeThroughHeight,
138
147
  strikeThroughColor
139
- } = _ref14;
148
+ } = _ref15;
140
149
  return {
141
150
  strikeThroughHeight,
142
151
  strikeThroughPosition,
143
152
  strikeThroughColor
144
153
  };
145
154
  };
146
- const PriceLockup = /*#__PURE__*/React.forwardRef((_ref15, ref) => {
155
+ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref16, ref) => {
147
156
  let {
148
157
  size = 'medium',
149
158
  signDirection = 'left',
@@ -160,7 +169,7 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref15, ref) => {
160
169
  tokens: priceLockupTokens,
161
170
  variant = {},
162
171
  ...rest
163
- } = _ref15;
172
+ } = _ref16;
164
173
  const viewport = useViewport();
165
174
  const {
166
175
  footnoteMarginTop,
@@ -193,6 +202,10 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref15, ref) => {
193
202
  const amount = hasCents ? priceString.substring(0, separatorPosition) : priceString;
194
203
  const cents = hasCents ? priceString.substring(separatorPosition + 1) : null;
195
204
  const renderTypography = (value, tokens, position) => {
205
+ const {
206
+ paddingTop,
207
+ ...restOfTokens
208
+ } = tokens;
196
209
  const customProps = position === 'bottom' ? {
197
210
  variant: {
198
211
  size: 'micro'
@@ -202,13 +215,16 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref15, ref) => {
202
215
  }
203
216
  } : {
204
217
  tokens: {
205
- ...tokens,
218
+ ...restOfTokens,
206
219
  color: fontColor
207
220
  }
208
221
  };
209
- return /*#__PURE__*/_jsx(Typography, {
210
- ...customProps,
211
- children: value
222
+ return /*#__PURE__*/_jsx(TypographyContainer, {
223
+ paddingTop: paddingTop,
224
+ children: /*#__PURE__*/_jsx(Typography, {
225
+ ...customProps,
226
+ children: value
227
+ })
212
228
  });
213
229
  };
214
230
  const renderCurrencySymbol = () => renderTypography(`${currencySymbol}`, typographyTokens.dollarSign);
@@ -7,12 +7,14 @@ export default _ref => {
7
7
  currencySymbolFontSize,
8
8
  currencySymbolLineHeight,
9
9
  currencySymbolFontWeight,
10
+ currencySymbolPaddingTop,
10
11
  amountFontSize,
11
12
  amountLineHeight,
12
13
  amountLetterSpacing,
13
14
  amountFontWeight,
14
15
  centsFontSize,
15
16
  centsLineHeight,
17
+ centsPaddingTop,
16
18
  rateFontSize,
17
19
  rateLineHeight,
18
20
  bottomTextFontSize,
@@ -28,7 +30,8 @@ export default _ref => {
28
30
  dollarSign: {
29
31
  fontSize: currencySymbolFontSize,
30
32
  lineHeight: currencySymbolLineHeight,
31
- fontWeight: currencySymbolFontWeight
33
+ fontWeight: currencySymbolFontWeight,
34
+ paddingTop: currencySymbolPaddingTop
32
35
  },
33
36
  amount: {
34
37
  color: fontColor,
@@ -40,7 +43,8 @@ export default _ref => {
40
43
  cents: {
41
44
  fontSize: centsFontSize,
42
45
  lineHeight: centsLineHeight,
43
- fontWeight: centsFontWeight
46
+ fontWeight: centsFontWeight,
47
+ paddingTop: centsPaddingTop
44
48
  },
45
49
  rate: {
46
50
  fontSize: rateFontSize,
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  ],
7
7
  "dependencies": {
8
8
  "@gorhom/portal": "^1.0.14",
9
- "@telus-uds/components-base": "^2.3.0",
9
+ "@telus-uds/components-base": "^2.4.0",
10
10
  "@telus-uds/system-constants": "^2.0.0",
11
11
  "fscreen": "^1.2.0",
12
12
  "lodash.omit": "^4.5.0",
@@ -14,7 +14,7 @@
14
14
  "react-dates": "^21.8.0",
15
15
  "react-helmet-async": "^1.3.0",
16
16
  "react-moment-proptypes": "^1.8.1",
17
- "@telus-uds/system-theme-tokens": "^3.2.0",
17
+ "@telus-uds/system-theme-tokens": "^3.3.0",
18
18
  "prop-types": "^15.7.2",
19
19
  "lodash.throttle": "^4.1.1",
20
20
  "react-youtube": "^10.1.0",
@@ -81,5 +81,5 @@
81
81
  "skip": true
82
82
  },
83
83
  "types": "types/index.d.ts",
84
- "version": "3.2.1"
84
+ "version": "3.3.0"
85
85
  }
@@ -24,8 +24,7 @@ import { htmlAttrs, styledComponents } from '../utils'
24
24
  const { styled } = styledComponents
25
25
 
26
26
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
27
- const dateFormat = 'DD / MM / YYYY'
28
- const dateFormatWithoutSpaces = 'DD/MM/YYYY'
27
+
29
28
  const getResponsiveDaySize = (inline = false, viewport = 'md') => {
30
29
  if (viewport === 'xs') {
31
30
  return inline ? undefined : 36
@@ -56,8 +55,6 @@ const PortalPositionedContainer = styled.div({
56
55
  top: ({ top }) => `${top}px`
57
56
  })
58
57
 
59
- const validDatePattern = /^([0-2][0-9]|3[0-1])(\/)(0[1-9]|1[0-2])\2(\d{4})$/
60
-
61
58
  const getInitialVisibleMonth = (initialVisibleMonth, inputDate) => {
62
59
  if (initialVisibleMonth === '' || inputDate instanceof moment) {
63
60
  return null
@@ -92,6 +89,7 @@ const DatePicker = React.forwardRef(
92
89
  copy = 'en',
93
90
  id,
94
91
  date,
92
+ dateFormat = 'DD / MM / YYYY',
95
93
  feedback,
96
94
  inline = false,
97
95
  isDayDisabled,
@@ -106,16 +104,20 @@ const DatePicker = React.forwardRef(
106
104
  disabled = false,
107
105
  prevTestID = '',
108
106
  nextTestID = '',
109
- placeholder = 'DD / MM / YYYY',
107
+ placeholder = dateFormat,
108
+
110
109
  initialVisibleMonth = '',
111
110
  ...rest
112
111
  },
113
112
  ref
114
113
  ) => {
115
114
  const [inputDate, setInputDate] = React.useState(date instanceof moment ? date : undefined)
115
+
116
116
  const [inputText, setInputText] = React.useState(
117
117
  date instanceof moment ? date.format(dateFormat) : ''
118
118
  )
119
+ const dateFormatWithoutSpaces = dateFormat.replace(/\s/g, '')
120
+
119
121
  const textInputRef = React.useRef()
120
122
  const prevButtonRef = React.useRef()
121
123
  const [datePickerPosition, setDatePickerPosition] = React.useState({ left: 0, top: 0 })
@@ -136,7 +138,7 @@ const DatePicker = React.forwardRef(
136
138
  const throttledUpdate = throttle(updateDatePickerPosition, 100, { leading: false })
137
139
 
138
140
  // Initial call to set the position
139
- updateDatePickerPosition()
141
+ throttledUpdate()
140
142
 
141
143
  // Register event listeners
142
144
  window.addEventListener('resize', throttledUpdate)
@@ -161,7 +163,7 @@ const DatePicker = React.forwardRef(
161
163
  setInputDate(date)
162
164
  setInputText(date instanceof moment ? date.format(dateFormat) : '')
163
165
  }
164
- }, [date, inputDate])
166
+ }, [date, inputDate, dateFormat])
165
167
 
166
168
  React.useEffect(() => {
167
169
  let timeoutId
@@ -241,7 +243,10 @@ const DatePicker = React.forwardRef(
241
243
  }
242
244
 
243
245
  const handleValidation = (inputValidation) => {
244
- if (validDatePattern.test(inputText.replace(/\s+/g, '')) === false && inputText !== '') {
246
+ const momentDate = moment(inputText, dateFormat, true)
247
+ const isValidDate = momentDate.isValid()
248
+
249
+ if (!isValidDate && inputText !== '') {
245
250
  return 'error'
246
251
  }
247
252
 
@@ -467,8 +472,11 @@ DatePicker.propTypes = {
467
472
  */
468
473
  date: momentPropTypes.momentObj,
469
474
  /**
470
- * A detailed description of validation error/success or additional instructions.
471
- * Visual variant is determined based on the `validation` prop.
475
+ * A Moment instance representing the currently selected date, i.e. `moment()`
476
+ */
477
+ dateFormat: PropTypes.string,
478
+ /**
479
+ * Optional date format for the date input. If not set, the default value will be `DD / MM / YYYY`
472
480
  */
473
481
  feedback: PropTypes.string,
474
482
  /**
@@ -524,7 +532,7 @@ DatePicker.propTypes = {
524
532
  */
525
533
  nextTestID: PropTypes.string,
526
534
  /**
527
- * Optional placeholder for the date input. If not set the default value will be `DD / MM / YYYY`
535
+ * Optional placeholder for the date input. If not set, the default value will be equal to the `dateFormat` prop
528
536
  */
529
537
  placeholder: PropTypes.string,
530
538
  /**
@@ -74,6 +74,10 @@ const StrikeThroughContainer = styled.div`
74
74
  position: absolute;
75
75
  }
76
76
  `
77
+ const TypographyContainer = styled.div`
78
+ display: flex;
79
+ padding-top: ${({ paddingTop }) => `${paddingTop || 0}px`};
80
+ `
77
81
 
78
82
  const selectFootnoteLinkStyles = ({
79
83
  footnoteLinkColor,
@@ -154,11 +158,17 @@ const PriceLockup = React.forwardRef(
154
158
  const cents = hasCents ? priceString.substring(separatorPosition + 1) : null
155
159
 
156
160
  const renderTypography = (value, tokens, position) => {
161
+ const { paddingTop, ...restOfTokens } = tokens
157
162
  const customProps =
158
163
  position === 'bottom'
159
164
  ? { variant: { size: 'micro' }, tokens: { color: fontColor } }
160
- : { tokens: { ...tokens, color: fontColor } }
161
- return <Typography {...customProps}>{value}</Typography>
165
+ : { tokens: { ...restOfTokens, color: fontColor } }
166
+
167
+ return (
168
+ <TypographyContainer paddingTop={paddingTop}>
169
+ <Typography {...customProps}>{value}</Typography>
170
+ </TypographyContainer>
171
+ )
162
172
  }
163
173
 
164
174
  const renderCurrencySymbol = () =>
@@ -6,12 +6,14 @@ export default ({
6
6
  currencySymbolFontSize,
7
7
  currencySymbolLineHeight,
8
8
  currencySymbolFontWeight,
9
+ currencySymbolPaddingTop,
9
10
  amountFontSize,
10
11
  amountLineHeight,
11
12
  amountLetterSpacing,
12
13
  amountFontWeight,
13
14
  centsFontSize,
14
15
  centsLineHeight,
16
+ centsPaddingTop,
15
17
  rateFontSize,
16
18
  rateLineHeight,
17
19
  bottomTextFontSize,
@@ -23,7 +25,8 @@ export default ({
23
25
  dollarSign: {
24
26
  fontSize: currencySymbolFontSize,
25
27
  lineHeight: currencySymbolLineHeight,
26
- fontWeight: currencySymbolFontWeight
28
+ fontWeight: currencySymbolFontWeight,
29
+ paddingTop: currencySymbolPaddingTop
27
30
  },
28
31
  amount: {
29
32
  color: fontColor,
@@ -32,7 +35,16 @@ export default ({
32
35
  letterSpacing: amountLetterSpacing,
33
36
  fontWeight: amountFontWeight
34
37
  },
35
- cents: { fontSize: centsFontSize, lineHeight: centsLineHeight, fontWeight: centsFontWeight },
36
- rate: { fontSize: rateFontSize, lineHeight: rateLineHeight, fontWeight: rateFontWeight },
38
+ cents: {
39
+ fontSize: centsFontSize,
40
+ lineHeight: centsLineHeight,
41
+ fontWeight: centsFontWeight,
42
+ paddingTop: centsPaddingTop
43
+ },
44
+ rate: {
45
+ fontSize: rateFontSize,
46
+ lineHeight: rateLineHeight,
47
+ fontWeight: rateFontWeight
48
+ },
37
49
  bottomText: { fontSize: bottomTextFontSize, lineHeight: bottomTextLineHeight }
38
50
  })
package/types/common.d.ts CHANGED
@@ -154,7 +154,7 @@ export interface PressableState {
154
154
  }
155
155
 
156
156
  // TODO: Make this more specific:
157
- // https://telus.com/universal-design-system/components/allium/skeleton/#props
157
+ // https://telus.com/universal-design-system/components/allium/Skeleton/#props
158
158
  export type SkeletonProps = Record<string, any>
159
159
 
160
160
  export type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'