@telus-uds/components-web 2.26.0 → 2.27.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,28 @@
1
1
  # Change Log - @telus-uds/components-web
2
2
 
3
- This log was last generated on Fri, 01 Dec 2023 20:57:37 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 13 Dec 2023 21:13:56 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 2.27.0
8
+
9
+ Wed, 13 Dec 2023 21:13:56 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - fixed WebVideo youtube callback type by adding event params (kristina.kirpichnikova@telus.com)
14
+ - Bump @telus-uds/components-base to v1.72.0
15
+ - Bump @telus-uds/system-theme-tokens to v2.48.0
16
+
17
+ ### Patches
18
+
19
+ - `DatePicker`: Fix stacking context and positioning issue (shahzaibkhalidmalik@outlook.com)
20
+ - fixes the size-by-height property (guillermo.peitzner@telus.com)
21
+ - adding colour toggle to imports (mauricio.batresmontejo@telus.com)
22
+
7
23
  ## 2.26.0
8
24
 
9
- Fri, 01 Dec 2023 20:57:37 GMT
25
+ Fri, 01 Dec 2023 21:08:36 GMT
10
26
 
11
27
  ### Minor changes
12
28
 
@@ -54,6 +54,24 @@ const DateInputWrapper = /*#__PURE__*/_styledComponents.default.div.withConfig({
54
54
  display: 'flex',
55
55
  flexDirection: 'column'
56
56
  });
57
+ const PortalPositionedContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
58
+ displayName: "DatePicker__PortalPositionedContainer",
59
+ componentId: "components-web__sc-mz8fi3-2"
60
+ })({
61
+ position: 'absolute',
62
+ left: _ref => {
63
+ let {
64
+ left
65
+ } = _ref;
66
+ return `${left}px`;
67
+ },
68
+ top: _ref2 => {
69
+ let {
70
+ top
71
+ } = _ref2;
72
+ return `${top}px`;
73
+ }
74
+ });
57
75
 
58
76
  /**
59
77
  * Use DatePicker to select a date on a calendar.
@@ -76,7 +94,7 @@ const DateInputWrapper = /*#__PURE__*/_styledComponents.default.div.withConfig({
76
94
  * - Optimized for keyboard interaction and tablet touch
77
95
  * - Recommended for viewports greater than or equal to 576px
78
96
  */
79
- const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
97
+ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
80
98
  var _dictionary$copy;
81
99
  let {
82
100
  copy = 'en',
@@ -97,9 +115,33 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
97
115
  prevTestID,
98
116
  nextTestID,
99
117
  ...rest
100
- } = _ref;
118
+ } = _ref3;
101
119
  const [inputDate, setInputDate] = (0, _react.useState)(date instanceof _moment.default ? date : undefined);
102
120
  const [inputText, setInputText] = (0, _react.useState)(date instanceof _moment.default ? date.format(dateFormat) : '');
121
+ const textInputRef = (0, _react.useRef)();
122
+ const [datePickerPosition, setDatePickerPosition] = (0, _react.useState)({
123
+ left: 0,
124
+ top: 0
125
+ });
126
+ (0, _componentsBase.useSafeLayoutEffect)(() => {
127
+ const updateDimensions = () => {
128
+ if (inline) return;
129
+ const {
130
+ left,
131
+ top
132
+ } = textInputRef.current.getBoundingClientRect();
133
+ setDatePickerPosition({
134
+ left,
135
+ top: top + textInputRef.current.offsetHeight
136
+ });
137
+ };
138
+ const throttledUpdateDimensions = (0, _lodash.throttle)(updateDimensions, 100, {
139
+ leading: false
140
+ });
141
+ updateDimensions();
142
+ window.addEventListener('resize', throttledUpdateDimensions);
143
+ return () => window.removeEventListener('resize', throttledUpdateDimensions);
144
+ }, []);
103
145
  const [isFocused, setIsFocused] = (0, _react.useState)(false);
104
146
  const [isClickedInside, setIsClickedInside] = (0, _react.useState)(false);
105
147
  const getCopy = (0, _componentsBase.useCopy)({
@@ -116,10 +158,10 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
116
158
  setInputText(date instanceof _moment.default ? date.format(dateFormat) : '');
117
159
  }
118
160
  }, [date, inputDate]);
119
- const onFocusChange = _ref2 => {
161
+ const onFocusChange = _ref4 => {
120
162
  let {
121
163
  focused
122
- } = _ref2;
164
+ } = _ref4;
123
165
  if (!isClickedInside) {
124
166
  setIsFocused(focused);
125
167
  }
@@ -164,7 +206,7 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
164
206
  const circleSize = getResponsiveCircleSize(inline, viewport);
165
207
  const HiddenInputFieldContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
166
208
  displayName: "DatePicker__HiddenInputFieldContainer",
167
- componentId: "components-web__sc-mz8fi3-2"
209
+ componentId: "components-web__sc-mz8fi3-3"
168
210
  })(["height:", ";width:", ";overflow:hidden;"], props => props.height, props => props.width);
169
211
  const {
170
212
  hiddenInputFieldContainerHeight,
@@ -190,10 +232,10 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
190
232
  fontName: remainingTokens.dayPickerWeekHeaderFontName,
191
233
  fontWeight: remainingTokens.dayPickerWeekHeaderFontWeight
192
234
  });
193
- const renderPrevButton = _ref3 => {
235
+ const renderPrevButton = _ref5 => {
194
236
  let {
195
237
  onClick
196
- } = _ref3;
238
+ } = _ref5;
197
239
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.IconButton, {
198
240
  onPress: () => {
199
241
  onClick();
@@ -205,10 +247,10 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
205
247
  testID: prevTestID
206
248
  });
207
249
  };
208
- const renderNextButton = _ref4 => {
250
+ const renderNextButton = _ref6 => {
209
251
  let {
210
252
  onClick
211
- } = _ref4;
253
+ } = _ref6;
212
254
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.IconButton, {
213
255
  onPress: () => {
214
256
  onClick();
@@ -220,18 +262,7 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
220
262
  testID: nextTestID
221
263
  });
222
264
  };
223
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarContainer.default, {
224
- ...selectProps(rest),
225
- daySize: daySize,
226
- validation: validation,
227
- remainingTokens: {
228
- ...remainingTokens
229
- },
230
- calendarDayDefaultHeight: circleSize,
231
- calendarDayDefaultWidth: circleSize,
232
- calendarMonthFontTokens: calendarMonthFontTokens,
233
- calendarWeekFontTokens: calendarWeekFontTokens,
234
- defaultFontTokens: defaultFontTokens,
265
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
235
266
  children: inline ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
236
267
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(HiddenInputFieldContainer, {
237
268
  height: hiddenInputFieldContainerHeight,
@@ -243,68 +274,33 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
243
274
  value: inputText,
244
275
  readOnly: true
245
276
  })
246
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DayPickerSingleDateController.default, {
247
- date: inputDate,
248
- onDateChange: onChange,
249
- focused: isFocused,
250
- onFocusChange: onFocusChange,
251
- numberOfMonths: 1,
252
- hideKeyboardShortcutsPanel: true,
253
- keepOpenOnDateSelect: false,
277
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarContainer.default, {
278
+ ...selectProps(rest),
254
279
  daySize: daySize,
255
- renderNavPrevButton: renderPrevButton,
256
- renderNavNextButton: renderNextButton,
257
- isOutsideRange: isDayDisabled,
258
- phrases: getCopy(),
259
- renderMonthElement: _ref5 => {
260
- let {
261
- month
262
- } = _ref5;
263
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(MonthCenterContainer, {
264
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
265
- children: [_dictionary.default[copy] ? _dictionary.default[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
266
- })
267
- });
268
- },
269
- renderWeekHeaderElement: day => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
270
- children: _dictionary.default[copy] ? _dictionary.default[copy].weekDays[day] : day
271
- })
272
- })]
273
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(DateInputWrapper, {
274
- onMouseDown: handleMouseDown,
275
- onFocus: handleFocus,
276
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.TextInput, {
277
- copy: copy,
278
- feedback: feedback,
279
- hint: hint,
280
- placeholder: "DD / MM / YYYY",
281
- onChange: onChangeInput,
282
- tooltip: tooltip,
283
- hintPosition: hintPosition,
284
- label: ((_dictionary$copy = _dictionary.default[copy]) === null || _dictionary$copy === void 0 ? void 0 : _dictionary$copy.roleDescription) ?? label,
285
- value: inputText,
286
280
  validation: validation,
287
- inactive: disabled,
288
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SingleDatePicker.default, {
281
+ remainingTokens: remainingTokens,
282
+ calendarDayDefaultHeight: circleSize,
283
+ calendarDayDefaultWidth: circleSize,
284
+ calendarMonthFontTokens: calendarMonthFontTokens,
285
+ calendarWeekFontTokens: calendarWeekFontTokens,
286
+ defaultFontTokens: defaultFontTokens,
287
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DayPickerSingleDateController.default, {
289
288
  date: inputDate,
290
- disabled: disabled,
291
289
  onDateChange: onChange,
292
290
  focused: isFocused,
293
291
  onFocusChange: onFocusChange,
294
292
  numberOfMonths: 1,
295
293
  hideKeyboardShortcutsPanel: true,
296
- keepOpenOnDateSelect: true,
294
+ keepOpenOnDateSelect: false,
297
295
  daySize: daySize,
298
- ref: ref,
299
296
  renderNavPrevButton: renderPrevButton,
297
+ renderNavNextButton: renderNextButton,
300
298
  isOutsideRange: isDayDisabled,
301
299
  phrases: getCopy(),
302
- id: id,
303
- renderNavNextButton: renderNextButton,
304
- renderMonthElement: _ref6 => {
300
+ renderMonthElement: _ref7 => {
305
301
  let {
306
302
  month
307
- } = _ref6;
303
+ } = _ref7;
308
304
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(MonthCenterContainer, {
309
305
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
310
306
  children: [_dictionary.default[copy] ? _dictionary.default[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
@@ -315,6 +311,70 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
315
311
  children: _dictionary.default[copy] ? _dictionary.default[copy].weekDays[day] : day
316
312
  })
317
313
  })
314
+ })]
315
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(DateInputWrapper, {
316
+ onMouseDown: handleMouseDown,
317
+ onFocus: handleFocus,
318
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.TextInput, {
319
+ copy: copy,
320
+ feedback: feedback,
321
+ hint: hint,
322
+ placeholder: "DD / MM / YYYY",
323
+ onChange: onChangeInput,
324
+ tooltip: tooltip,
325
+ hintPosition: hintPosition,
326
+ label: ((_dictionary$copy = _dictionary.default[copy]) === null || _dictionary$copy === void 0 ? void 0 : _dictionary$copy.roleDescription) ?? label,
327
+ value: inputText,
328
+ validation: validation,
329
+ inactive: disabled,
330
+ ref: textInputRef,
331
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Portal, {
332
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(PortalPositionedContainer, {
333
+ top: datePickerPosition.top,
334
+ left: datePickerPosition.left,
335
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarContainer.default, {
336
+ ...selectProps(rest),
337
+ daySize: daySize,
338
+ validation: validation,
339
+ remainingTokens: remainingTokens,
340
+ calendarDayDefaultHeight: circleSize,
341
+ calendarDayDefaultWidth: circleSize,
342
+ calendarMonthFontTokens: calendarMonthFontTokens,
343
+ calendarWeekFontTokens: calendarWeekFontTokens,
344
+ defaultFontTokens: defaultFontTokens,
345
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SingleDatePicker.default, {
346
+ date: inputDate,
347
+ disabled: disabled,
348
+ onDateChange: onChange,
349
+ focused: isFocused,
350
+ onFocusChange: onFocusChange,
351
+ numberOfMonths: 1,
352
+ hideKeyboardShortcutsPanel: true,
353
+ keepOpenOnDateSelect: true,
354
+ daySize: daySize,
355
+ ref: ref,
356
+ renderNavPrevButton: renderPrevButton,
357
+ isOutsideRange: isDayDisabled,
358
+ phrases: getCopy(),
359
+ id: id,
360
+ renderNavNextButton: renderNextButton,
361
+ renderMonthElement: _ref8 => {
362
+ let {
363
+ month
364
+ } = _ref8;
365
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(MonthCenterContainer, {
366
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
367
+ children: [_dictionary.default[copy] ? _dictionary.default[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
368
+ })
369
+ });
370
+ },
371
+ renderWeekHeaderElement: day => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
372
+ children: _dictionary.default[copy] ? _dictionary.default[copy].weekDays[day] : day
373
+ })
374
+ })
375
+ })
376
+ })
377
+ })
318
378
  })
319
379
  })
320
380
  });
@@ -42,7 +42,7 @@ const OptimizeImage = _ref => {
42
42
  mdSrc: (0, _utils.getOptimizedUrl)(contentfulAssetUrl, dimension, md, quality, disableRetina, supportsWebp),
43
43
  lgSrc: (0, _utils.getOptimizedUrl)(contentfulAssetUrl, dimension, lg, quality, disableRetina, supportsWebp),
44
44
  xlSrc: (0, _utils.getOptimizedUrl)(contentfulAssetUrl, dimension, xl, quality, disableRetina, supportsWebp),
45
- fallbackSrc: (0, _utils.getFallbackUrl)(contentfulAssetUrl, xl, quality)
45
+ fallbackSrc: (0, _utils.getFallbackUrl)(contentfulAssetUrl, dimension, xl, quality)
46
46
  });
47
47
  });
48
48
  }, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs]);
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = getFallbackUrl;
7
7
  var _isSvgUrl = _interopRequireDefault(require("./isSvgUrl"));
8
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
- function getFallbackUrl(url, width, quality) {
9
+ function getFallbackUrl(url, dimension, size, quality) {
10
10
  if (!(0, _isSvgUrl.default)(url)) {
11
- return `${url}?w=${width}&q=${quality}`;
11
+ return `${url}?${dimension}=${size}&q=${quality}`;
12
12
  }
13
13
  return url;
14
14
  }
@@ -93,6 +93,12 @@ Object.defineProperty(exports, "ChevronLink", {
93
93
  return _componentsBase.ChevronLink;
94
94
  }
95
95
  });
96
+ Object.defineProperty(exports, "ColourToggle", {
97
+ enumerable: true,
98
+ get: function () {
99
+ return _componentsBase.ColourToggle;
100
+ }
101
+ });
96
102
  Object.defineProperty(exports, "Divider", {
97
103
  enumerable: true,
98
104
  get: function () {
@@ -1,13 +1,13 @@
1
- import React, { forwardRef, useEffect, useState } from 'react';
1
+ import React, { forwardRef, useEffect, useState, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
  import momentPropTypes from 'react-moment-proptypes';
5
5
  import 'react-dates/initialize';
6
6
  import SingleDatePicker from 'react-dates/lib/components/SingleDatePicker';
7
7
  import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerSingleDateController';
8
- import { IconButton, TextInput, selectSystemProps, useCopy, useViewport, useThemeTokens, applyTextStyles, getTokensPropType } from '@telus-uds/components-base';
8
+ import { IconButton, TextInput, selectSystemProps, useCopy, useViewport, useThemeTokens, applyTextStyles, getTokensPropType, Portal, useSafeLayoutEffect } from '@telus-uds/components-base';
9
9
  import moment from 'moment';
10
- import { isUndefined } from 'lodash';
10
+ import { isUndefined, throttle } from 'lodash';
11
11
  import CalendarContainer from './CalendarContainer';
12
12
  import dictionary from './dictionary';
13
13
  import { htmlAttrs } from '../utils';
@@ -47,6 +47,24 @@ const DateInputWrapper = /*#__PURE__*/styled.div.withConfig({
47
47
  display: 'flex',
48
48
  flexDirection: 'column'
49
49
  });
50
+ const PortalPositionedContainer = /*#__PURE__*/styled.div.withConfig({
51
+ displayName: "DatePicker__PortalPositionedContainer",
52
+ componentId: "components-web__sc-mz8fi3-2"
53
+ })({
54
+ position: 'absolute',
55
+ left: _ref => {
56
+ let {
57
+ left
58
+ } = _ref;
59
+ return `${left}px`;
60
+ },
61
+ top: _ref2 => {
62
+ let {
63
+ top
64
+ } = _ref2;
65
+ return `${top}px`;
66
+ }
67
+ });
50
68
 
51
69
  /**
52
70
  * Use DatePicker to select a date on a calendar.
@@ -69,7 +87,7 @@ const DateInputWrapper = /*#__PURE__*/styled.div.withConfig({
69
87
  * - Optimized for keyboard interaction and tablet touch
70
88
  * - Recommended for viewports greater than or equal to 576px
71
89
  */
72
- const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
90
+ const DatePicker = /*#__PURE__*/forwardRef((_ref3, ref) => {
73
91
  var _dictionary$copy;
74
92
  let {
75
93
  copy = 'en',
@@ -90,9 +108,33 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
90
108
  prevTestID,
91
109
  nextTestID,
92
110
  ...rest
93
- } = _ref;
111
+ } = _ref3;
94
112
  const [inputDate, setInputDate] = useState(date instanceof moment ? date : undefined);
95
113
  const [inputText, setInputText] = useState(date instanceof moment ? date.format(dateFormat) : '');
114
+ const textInputRef = useRef();
115
+ const [datePickerPosition, setDatePickerPosition] = useState({
116
+ left: 0,
117
+ top: 0
118
+ });
119
+ useSafeLayoutEffect(() => {
120
+ const updateDimensions = () => {
121
+ if (inline) return;
122
+ const {
123
+ left,
124
+ top
125
+ } = textInputRef.current.getBoundingClientRect();
126
+ setDatePickerPosition({
127
+ left,
128
+ top: top + textInputRef.current.offsetHeight
129
+ });
130
+ };
131
+ const throttledUpdateDimensions = throttle(updateDimensions, 100, {
132
+ leading: false
133
+ });
134
+ updateDimensions();
135
+ window.addEventListener('resize', throttledUpdateDimensions);
136
+ return () => window.removeEventListener('resize', throttledUpdateDimensions);
137
+ }, []);
96
138
  const [isFocused, setIsFocused] = useState(false);
97
139
  const [isClickedInside, setIsClickedInside] = useState(false);
98
140
  const getCopy = useCopy({
@@ -109,10 +151,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
109
151
  setInputText(date instanceof moment ? date.format(dateFormat) : '');
110
152
  }
111
153
  }, [date, inputDate]);
112
- const onFocusChange = _ref2 => {
154
+ const onFocusChange = _ref4 => {
113
155
  let {
114
156
  focused
115
- } = _ref2;
157
+ } = _ref4;
116
158
  if (!isClickedInside) {
117
159
  setIsFocused(focused);
118
160
  }
@@ -157,7 +199,7 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
157
199
  const circleSize = getResponsiveCircleSize(inline, viewport);
158
200
  const HiddenInputFieldContainer = /*#__PURE__*/styled.div.withConfig({
159
201
  displayName: "DatePicker__HiddenInputFieldContainer",
160
- componentId: "components-web__sc-mz8fi3-2"
202
+ componentId: "components-web__sc-mz8fi3-3"
161
203
  })(["height:", ";width:", ";overflow:hidden;"], props => props.height, props => props.width);
162
204
  const {
163
205
  hiddenInputFieldContainerHeight,
@@ -183,10 +225,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
183
225
  fontName: remainingTokens.dayPickerWeekHeaderFontName,
184
226
  fontWeight: remainingTokens.dayPickerWeekHeaderFontWeight
185
227
  });
186
- const renderPrevButton = _ref3 => {
228
+ const renderPrevButton = _ref5 => {
187
229
  let {
188
230
  onClick
189
- } = _ref3;
231
+ } = _ref5;
190
232
  return /*#__PURE__*/_jsx(IconButton, {
191
233
  onPress: () => {
192
234
  onClick();
@@ -198,10 +240,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
198
240
  testID: prevTestID
199
241
  });
200
242
  };
201
- const renderNextButton = _ref4 => {
243
+ const renderNextButton = _ref6 => {
202
244
  let {
203
245
  onClick
204
- } = _ref4;
246
+ } = _ref6;
205
247
  return /*#__PURE__*/_jsx(IconButton, {
206
248
  onPress: () => {
207
249
  onClick();
@@ -213,18 +255,7 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
213
255
  testID: nextTestID
214
256
  });
215
257
  };
216
- return /*#__PURE__*/_jsx(CalendarContainer, {
217
- ...selectProps(rest),
218
- daySize: daySize,
219
- validation: validation,
220
- remainingTokens: {
221
- ...remainingTokens
222
- },
223
- calendarDayDefaultHeight: circleSize,
224
- calendarDayDefaultWidth: circleSize,
225
- calendarMonthFontTokens: calendarMonthFontTokens,
226
- calendarWeekFontTokens: calendarWeekFontTokens,
227
- defaultFontTokens: defaultFontTokens,
258
+ return /*#__PURE__*/_jsx(_Fragment, {
228
259
  children: inline ? /*#__PURE__*/_jsxs(_Fragment, {
229
260
  children: [/*#__PURE__*/_jsx(HiddenInputFieldContainer, {
230
261
  height: hiddenInputFieldContainerHeight,
@@ -236,68 +267,33 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
236
267
  value: inputText,
237
268
  readOnly: true
238
269
  })
239
- }), /*#__PURE__*/_jsx(DayPickerSingleDateController, {
240
- date: inputDate,
241
- onDateChange: onChange,
242
- focused: isFocused,
243
- onFocusChange: onFocusChange,
244
- numberOfMonths: 1,
245
- hideKeyboardShortcutsPanel: true,
246
- keepOpenOnDateSelect: false,
270
+ }), /*#__PURE__*/_jsx(CalendarContainer, {
271
+ ...selectProps(rest),
247
272
  daySize: daySize,
248
- renderNavPrevButton: renderPrevButton,
249
- renderNavNextButton: renderNextButton,
250
- isOutsideRange: isDayDisabled,
251
- phrases: getCopy(),
252
- renderMonthElement: _ref5 => {
253
- let {
254
- month
255
- } = _ref5;
256
- return /*#__PURE__*/_jsx(MonthCenterContainer, {
257
- children: /*#__PURE__*/_jsxs("div", {
258
- children: [dictionary[copy] ? dictionary[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
259
- })
260
- });
261
- },
262
- renderWeekHeaderElement: day => /*#__PURE__*/_jsx("div", {
263
- children: dictionary[copy] ? dictionary[copy].weekDays[day] : day
264
- })
265
- })]
266
- }) : /*#__PURE__*/_jsx(DateInputWrapper, {
267
- onMouseDown: handleMouseDown,
268
- onFocus: handleFocus,
269
- children: /*#__PURE__*/_jsx(TextInput, {
270
- copy: copy,
271
- feedback: feedback,
272
- hint: hint,
273
- placeholder: "DD / MM / YYYY",
274
- onChange: onChangeInput,
275
- tooltip: tooltip,
276
- hintPosition: hintPosition,
277
- label: ((_dictionary$copy = dictionary[copy]) === null || _dictionary$copy === void 0 ? void 0 : _dictionary$copy.roleDescription) ?? label,
278
- value: inputText,
279
273
  validation: validation,
280
- inactive: disabled,
281
- children: /*#__PURE__*/_jsx(SingleDatePicker, {
274
+ remainingTokens: remainingTokens,
275
+ calendarDayDefaultHeight: circleSize,
276
+ calendarDayDefaultWidth: circleSize,
277
+ calendarMonthFontTokens: calendarMonthFontTokens,
278
+ calendarWeekFontTokens: calendarWeekFontTokens,
279
+ defaultFontTokens: defaultFontTokens,
280
+ children: /*#__PURE__*/_jsx(DayPickerSingleDateController, {
282
281
  date: inputDate,
283
- disabled: disabled,
284
282
  onDateChange: onChange,
285
283
  focused: isFocused,
286
284
  onFocusChange: onFocusChange,
287
285
  numberOfMonths: 1,
288
286
  hideKeyboardShortcutsPanel: true,
289
- keepOpenOnDateSelect: true,
287
+ keepOpenOnDateSelect: false,
290
288
  daySize: daySize,
291
- ref: ref,
292
289
  renderNavPrevButton: renderPrevButton,
290
+ renderNavNextButton: renderNextButton,
293
291
  isOutsideRange: isDayDisabled,
294
292
  phrases: getCopy(),
295
- id: id,
296
- renderNavNextButton: renderNextButton,
297
- renderMonthElement: _ref6 => {
293
+ renderMonthElement: _ref7 => {
298
294
  let {
299
295
  month
300
- } = _ref6;
296
+ } = _ref7;
301
297
  return /*#__PURE__*/_jsx(MonthCenterContainer, {
302
298
  children: /*#__PURE__*/_jsxs("div", {
303
299
  children: [dictionary[copy] ? dictionary[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
@@ -308,6 +304,70 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
308
304
  children: dictionary[copy] ? dictionary[copy].weekDays[day] : day
309
305
  })
310
306
  })
307
+ })]
308
+ }) : /*#__PURE__*/_jsx(DateInputWrapper, {
309
+ onMouseDown: handleMouseDown,
310
+ onFocus: handleFocus,
311
+ children: /*#__PURE__*/_jsx(TextInput, {
312
+ copy: copy,
313
+ feedback: feedback,
314
+ hint: hint,
315
+ placeholder: "DD / MM / YYYY",
316
+ onChange: onChangeInput,
317
+ tooltip: tooltip,
318
+ hintPosition: hintPosition,
319
+ label: ((_dictionary$copy = dictionary[copy]) === null || _dictionary$copy === void 0 ? void 0 : _dictionary$copy.roleDescription) ?? label,
320
+ value: inputText,
321
+ validation: validation,
322
+ inactive: disabled,
323
+ ref: textInputRef,
324
+ children: /*#__PURE__*/_jsx(Portal, {
325
+ children: /*#__PURE__*/_jsx(PortalPositionedContainer, {
326
+ top: datePickerPosition.top,
327
+ left: datePickerPosition.left,
328
+ children: /*#__PURE__*/_jsx(CalendarContainer, {
329
+ ...selectProps(rest),
330
+ daySize: daySize,
331
+ validation: validation,
332
+ remainingTokens: remainingTokens,
333
+ calendarDayDefaultHeight: circleSize,
334
+ calendarDayDefaultWidth: circleSize,
335
+ calendarMonthFontTokens: calendarMonthFontTokens,
336
+ calendarWeekFontTokens: calendarWeekFontTokens,
337
+ defaultFontTokens: defaultFontTokens,
338
+ children: /*#__PURE__*/_jsx(SingleDatePicker, {
339
+ date: inputDate,
340
+ disabled: disabled,
341
+ onDateChange: onChange,
342
+ focused: isFocused,
343
+ onFocusChange: onFocusChange,
344
+ numberOfMonths: 1,
345
+ hideKeyboardShortcutsPanel: true,
346
+ keepOpenOnDateSelect: true,
347
+ daySize: daySize,
348
+ ref: ref,
349
+ renderNavPrevButton: renderPrevButton,
350
+ isOutsideRange: isDayDisabled,
351
+ phrases: getCopy(),
352
+ id: id,
353
+ renderNavNextButton: renderNextButton,
354
+ renderMonthElement: _ref8 => {
355
+ let {
356
+ month
357
+ } = _ref8;
358
+ return /*#__PURE__*/_jsx(MonthCenterContainer, {
359
+ children: /*#__PURE__*/_jsxs("div", {
360
+ children: [dictionary[copy] ? dictionary[copy].months[month.month()] : month.format('MMMM'), ' ', month.year()]
361
+ })
362
+ });
363
+ },
364
+ renderWeekHeaderElement: day => /*#__PURE__*/_jsx("div", {
365
+ children: dictionary[copy] ? dictionary[copy].weekDays[day] : day
366
+ })
367
+ })
368
+ })
369
+ })
370
+ })
311
371
  })
312
372
  })
313
373
  });
@@ -33,7 +33,7 @@ const OptimizeImage = _ref => {
33
33
  mdSrc: getOptimizedUrl(contentfulAssetUrl, dimension, md, quality, disableRetina, supportsWebp),
34
34
  lgSrc: getOptimizedUrl(contentfulAssetUrl, dimension, lg, quality, disableRetina, supportsWebp),
35
35
  xlSrc: getOptimizedUrl(contentfulAssetUrl, dimension, xl, quality, disableRetina, supportsWebp),
36
- fallbackSrc: getFallbackUrl(contentfulAssetUrl, xl, quality)
36
+ fallbackSrc: getFallbackUrl(contentfulAssetUrl, dimension, xl, quality)
37
37
  });
38
38
  });
39
39
  }, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs]);
@@ -1,7 +1,7 @@
1
1
  import isSvgUrl from './isSvgUrl';
2
- export default function getFallbackUrl(url, width, quality) {
2
+ export default function getFallbackUrl(url, dimension, size, quality) {
3
3
  if (!isSvgUrl(url)) {
4
- return `${url}?w=${width}&q=${quality}`;
4
+ return `${url}?${dimension}=${size}&q=${quality}`;
5
5
  }
6
6
  return url;
7
7
  }
@@ -5,7 +5,7 @@ export {
5
5
  /**
6
6
  * Most base components should be re-exported as-is.
7
7
  */
8
- A11yText, ActivityIndicator, Autocomplete, Box, Button, BaseProvider, A11yInfoProvider, ViewportProvider, ThemeProvider, ButtonDropdown, ButtonGroup, ButtonLink, Carousel, CarouselTabs, Checkbox, CheckboxGroup, ChevronLink, Divider, ExpandCollapse, Feedback, FlexGrid, Icon, InputLabel, InputSupports, Link, Listbox, Modal, MultiSelectFilter, Notification, Pagination, QuickLinks, QuickLinksFeature, Radio, RadioGroup, RadioCard, RadioCardGroup, Responsive, Search, Select, SideNav, Skeleton, SkipLink, Spacer, StackView, StackWrap, StepTracker, Tabs, Tags, TextButton, TextArea, TextInput, Timeline, ToggleSwitch, ToggleSwitchGroup, TooltipButton, Tooltip, Typography, Validator,
8
+ A11yText, ActivityIndicator, Autocomplete, Box, Button, BaseProvider, A11yInfoProvider, ViewportProvider, ThemeProvider, ButtonDropdown, ButtonGroup, ButtonLink, Carousel, CarouselTabs, Checkbox, CheckboxGroup, ChevronLink, ColourToggle, Divider, ExpandCollapse, Feedback, FlexGrid, Icon, InputLabel, InputSupports, Link, Listbox, Modal, MultiSelectFilter, Notification, Pagination, QuickLinks, QuickLinksFeature, Radio, RadioGroup, RadioCard, RadioCardGroup, Responsive, Search, Select, SideNav, Skeleton, SkipLink, Spacer, StackView, StackWrap, StepTracker, Tabs, Tags, TextButton, TextArea, TextInput, Timeline, ToggleSwitch, ToggleSwitchGroup, TooltipButton, Tooltip, Typography, Validator,
9
9
  /*
10
10
  * Most utilities exported from @telus-uds/components-base are for building systems, not apps.
11
11
  * Re-export only those utilities with a stable API and known use cases within apps / pages.
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.71.0",
8
+ "@telus-uds/components-base": "1.72.0",
9
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.47.0",
15
+ "@telus-uds/system-theme-tokens": "^2.48.0",
16
16
  "prop-types": "^15.7.2",
17
17
  "lodash.throttle": "^4.1.1",
18
18
  "react-youtube": "^10.1.0",
@@ -62,5 +62,5 @@
62
62
  "skip": true
63
63
  },
64
64
  "types": "types/index.d.ts",
65
- "version": "2.26.0"
65
+ "version": "2.27.0"
66
66
  }
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useEffect, useState } from 'react'
1
+ import React, { forwardRef, useEffect, useState, useRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import styled from 'styled-components'
4
4
  import momentPropTypes from 'react-moment-proptypes'
@@ -13,10 +13,12 @@ import {
13
13
  useViewport,
14
14
  useThemeTokens,
15
15
  applyTextStyles,
16
- getTokensPropType
16
+ getTokensPropType,
17
+ Portal,
18
+ useSafeLayoutEffect
17
19
  } from '@telus-uds/components-base'
18
20
  import moment from 'moment'
19
- import { isUndefined } from 'lodash'
21
+ import { isUndefined, throttle } from 'lodash'
20
22
  import CalendarContainer from './CalendarContainer'
21
23
  import dictionary from './dictionary'
22
24
  import { htmlAttrs } from '../utils'
@@ -48,6 +50,12 @@ const DateInputWrapper = styled.div({
48
50
  flexDirection: 'column'
49
51
  })
50
52
 
53
+ const PortalPositionedContainer = styled.div({
54
+ position: 'absolute',
55
+ left: ({ left }) => `${left}px`,
56
+ top: ({ top }) => `${top}px`
57
+ })
58
+
51
59
  /**
52
60
  * Use DatePicker to select a date on a calendar.
53
61
  *
@@ -97,6 +105,23 @@ const DatePicker = forwardRef(
97
105
  const [inputText, setInputText] = useState(
98
106
  date instanceof moment ? date.format(dateFormat) : ''
99
107
  )
108
+ const textInputRef = useRef()
109
+ const [datePickerPosition, setDatePickerPosition] = useState({ left: 0, top: 0 })
110
+
111
+ useSafeLayoutEffect(() => {
112
+ const updateDimensions = () => {
113
+ if (inline) return
114
+ const { left, top } = textInputRef.current.getBoundingClientRect()
115
+ setDatePickerPosition({
116
+ left,
117
+ top: top + textInputRef.current.offsetHeight
118
+ })
119
+ }
120
+ const throttledUpdateDimensions = throttle(updateDimensions, 100, { leading: false })
121
+ updateDimensions()
122
+ window.addEventListener('resize', throttledUpdateDimensions)
123
+ return () => window.removeEventListener('resize', throttledUpdateDimensions)
124
+ }, [])
100
125
 
101
126
  const [isFocused, setIsFocused] = useState(false)
102
127
  const [isClickedInside, setIsClickedInside] = useState(false)
@@ -204,19 +229,7 @@ const DatePicker = forwardRef(
204
229
  />
205
230
  )
206
231
  return (
207
- <CalendarContainer
208
- {...selectProps(rest)}
209
- daySize={daySize}
210
- validation={validation}
211
- remainingTokens={{
212
- ...remainingTokens
213
- }}
214
- calendarDayDefaultHeight={circleSize}
215
- calendarDayDefaultWidth={circleSize}
216
- calendarMonthFontTokens={calendarMonthFontTokens}
217
- calendarWeekFontTokens={calendarWeekFontTokens}
218
- defaultFontTokens={defaultFontTokens}
219
- >
232
+ <>
220
233
  {inline ? (
221
234
  <>
222
235
  <HiddenInputFieldContainer
@@ -225,65 +238,30 @@ const DatePicker = forwardRef(
225
238
  >
226
239
  <input ref={ref} id={id} type="text" value={inputText} readOnly />
227
240
  </HiddenInputFieldContainer>
228
- <DayPickerSingleDateController
229
- date={inputDate}
230
- onDateChange={onChange}
231
- focused={isFocused}
232
- onFocusChange={onFocusChange}
233
- numberOfMonths={1}
234
- hideKeyboardShortcutsPanel={true}
235
- keepOpenOnDateSelect={false}
241
+ <CalendarContainer
242
+ {...selectProps(rest)}
236
243
  daySize={daySize}
237
- renderNavPrevButton={renderPrevButton}
238
- renderNavNextButton={renderNextButton}
239
- isOutsideRange={isDayDisabled}
240
- phrases={getCopy()}
241
- renderMonthElement={({ month }) => (
242
- <MonthCenterContainer>
243
- <div>
244
- {dictionary[copy]
245
- ? dictionary[copy].months[month.month()]
246
- : month.format('MMMM')}{' '}
247
- {month.year()}
248
- </div>
249
- </MonthCenterContainer>
250
- )}
251
- renderWeekHeaderElement={(day) => (
252
- <div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
253
- )}
254
- />
255
- </>
256
- ) : (
257
- <DateInputWrapper onMouseDown={handleMouseDown} onFocus={handleFocus}>
258
- <TextInput
259
- copy={copy}
260
- feedback={feedback}
261
- hint={hint}
262
- placeholder="DD / MM / YYYY"
263
- onChange={onChangeInput}
264
- tooltip={tooltip}
265
- hintPosition={hintPosition}
266
- label={dictionary[copy]?.roleDescription ?? label}
267
- value={inputText}
268
244
  validation={validation}
269
- inactive={disabled}
245
+ remainingTokens={remainingTokens}
246
+ calendarDayDefaultHeight={circleSize}
247
+ calendarDayDefaultWidth={circleSize}
248
+ calendarMonthFontTokens={calendarMonthFontTokens}
249
+ calendarWeekFontTokens={calendarWeekFontTokens}
250
+ defaultFontTokens={defaultFontTokens}
270
251
  >
271
- <SingleDatePicker
252
+ <DayPickerSingleDateController
272
253
  date={inputDate}
273
- disabled={disabled}
274
254
  onDateChange={onChange}
275
255
  focused={isFocused}
276
256
  onFocusChange={onFocusChange}
277
257
  numberOfMonths={1}
278
258
  hideKeyboardShortcutsPanel={true}
279
- keepOpenOnDateSelect={true}
259
+ keepOpenOnDateSelect={false}
280
260
  daySize={daySize}
281
- ref={ref}
282
261
  renderNavPrevButton={renderPrevButton}
262
+ renderNavNextButton={renderNextButton}
283
263
  isOutsideRange={isDayDisabled}
284
264
  phrases={getCopy()}
285
- id={id}
286
- renderNavNextButton={renderNextButton}
287
265
  renderMonthElement={({ month }) => (
288
266
  <MonthCenterContainer>
289
267
  <div>
@@ -298,10 +276,94 @@ const DatePicker = forwardRef(
298
276
  <div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
299
277
  )}
300
278
  />
279
+ </CalendarContainer>
280
+ </>
281
+ ) : (
282
+ <DateInputWrapper onMouseDown={handleMouseDown} onFocus={handleFocus}>
283
+ <TextInput
284
+ copy={copy}
285
+ feedback={feedback}
286
+ hint={hint}
287
+ placeholder="DD / MM / YYYY"
288
+ onChange={onChangeInput}
289
+ tooltip={tooltip}
290
+ hintPosition={hintPosition}
291
+ label={dictionary[copy]?.roleDescription ?? label}
292
+ value={inputText}
293
+ validation={validation}
294
+ inactive={disabled}
295
+ ref={textInputRef}
296
+ >
297
+ <Portal>
298
+ {/* Because `SingleDatePicker` is an absolutely positioned element,
299
+ * putting it in a `Portal` breaks view heirarchy because it doesn't
300
+ * align with `TextInput`, but rather position itself with the nearest
301
+ * positioned ancestor.
302
+ *
303
+ * This means that the `Portal` needs to be positioned absolutely,
304
+ * but the `SingleDatePicker` needs to be positioned relative to the
305
+ * `Portal`.
306
+ *
307
+ * This is accomplished by wrapping the `SingleDatePicker` in a
308
+ * `PortalPositionedContainer` which positions the `SingleDatePicker`
309
+ * relative to the `Portal`. This container is then positioned absolutely
310
+ * relative to the `TextInput`.
311
+ *
312
+ * TODO: Using `floating-ui` or something like that is a more preferred and streamlined way
313
+ * to position popovers and overlays.
314
+ */}
315
+ <PortalPositionedContainer
316
+ top={datePickerPosition.top}
317
+ left={datePickerPosition.left}
318
+ >
319
+ <CalendarContainer
320
+ {...selectProps(rest)}
321
+ daySize={daySize}
322
+ validation={validation}
323
+ remainingTokens={remainingTokens}
324
+ calendarDayDefaultHeight={circleSize}
325
+ calendarDayDefaultWidth={circleSize}
326
+ calendarMonthFontTokens={calendarMonthFontTokens}
327
+ calendarWeekFontTokens={calendarWeekFontTokens}
328
+ defaultFontTokens={defaultFontTokens}
329
+ >
330
+ <SingleDatePicker
331
+ date={inputDate}
332
+ disabled={disabled}
333
+ onDateChange={onChange}
334
+ focused={isFocused}
335
+ onFocusChange={onFocusChange}
336
+ numberOfMonths={1}
337
+ hideKeyboardShortcutsPanel={true}
338
+ keepOpenOnDateSelect={true}
339
+ daySize={daySize}
340
+ ref={ref}
341
+ renderNavPrevButton={renderPrevButton}
342
+ isOutsideRange={isDayDisabled}
343
+ phrases={getCopy()}
344
+ id={id}
345
+ renderNavNextButton={renderNextButton}
346
+ renderMonthElement={({ month }) => (
347
+ <MonthCenterContainer>
348
+ <div>
349
+ {dictionary[copy]
350
+ ? dictionary[copy].months[month.month()]
351
+ : month.format('MMMM')}{' '}
352
+ {month.year()}
353
+ </div>
354
+ </MonthCenterContainer>
355
+ )}
356
+ renderWeekHeaderElement={(day) => (
357
+ <div>{dictionary[copy] ? dictionary[copy].weekDays[day] : day}</div>
358
+ )}
359
+ />
360
+ </CalendarContainer>
361
+ </PortalPositionedContainer>
362
+ </Portal>
301
363
  </TextInput>
302
364
  </DateInputWrapper>
303
365
  )}
304
- </CalendarContainer>
366
+ </>
305
367
  )
306
368
  }
307
369
  )
@@ -69,7 +69,7 @@ const OptimizeImage = ({
69
69
  disableRetina,
70
70
  supportsWebp
71
71
  ),
72
- fallbackSrc: getFallbackUrl(contentfulAssetUrl, xl, quality)
72
+ fallbackSrc: getFallbackUrl(contentfulAssetUrl, dimension, xl, quality)
73
73
  })
74
74
  })
75
75
  }, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs])
@@ -1,8 +1,8 @@
1
1
  import isSvgUrl from './isSvgUrl'
2
2
 
3
- export default function getFallbackUrl(url, width, quality) {
3
+ export default function getFallbackUrl(url, dimension, size, quality) {
4
4
  if (!isSvgUrl(url)) {
5
- return `${url}?w=${width}&q=${quality}`
5
+ return `${url}?${dimension}=${size}&q=${quality}`
6
6
  }
7
7
 
8
8
  return url
@@ -22,6 +22,7 @@ export {
22
22
  Checkbox,
23
23
  CheckboxGroup,
24
24
  ChevronLink,
25
+ ColourToggle,
25
26
  Divider,
26
27
  ExpandCollapse,
27
28
  Feedback,
@@ -1,4 +1,5 @@
1
1
  import type { ComponentType } from 'react'
2
+ import { YouTubeEvent } from 'react-youtube'
2
3
  import type { HTMLAttrs } from './common'
3
4
 
4
5
  export interface WebVideoProps extends HTMLAttrs {
@@ -10,9 +11,9 @@ export interface WebVideoProps extends HTMLAttrs {
10
11
  videoLength: number
11
12
  copy?: 'en' | 'fr'
12
13
  onStart?: () => void
13
- onPlay?: () => void
14
- onEnd?: () => void
15
- onPause?: () => void
14
+ onPlay?: (event: YouTubeEvent<number>) => void
15
+ onEnd?: (event: YouTubeEvent<number>) => void
16
+ onPause?: (event: YouTubeEvent<number>) => void
16
17
  }
17
18
 
18
19
  declare const WebVideo: ComponentType<WebVideoProps>