@telus-uds/components-web 1.9.0 → 1.10.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,26 @@
1
1
  # Change Log - @telus-uds/components-web
2
2
 
3
- This log was last generated on Thu, 27 Apr 2023 14:32:16 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 01 May 2023 22:02:12 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 1.10.0
8
+
9
+ Mon, 01 May 2023 22:02:12 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Footnote`: Allow `content` prop to take custom JSX, override copy with custom `dictionary` (shahzaibkhalidmalik@outlook.com)
14
+ - Set Item size to micro in Breadcrumbs (wlsdud194@hotmail.com)
15
+ - List Box merged with List changes (akshay.pandey1@telus.com)
16
+ - Added label to Breadcrumb component (wlsdud194@hotmail.com)
17
+ - update snapshots (kyle.king2@telus.com)
18
+ - Bump @telus-uds/components-base to v1.39.0
19
+ - Bump @telus-uds/system-theme-tokens to v2.24.0
20
+
7
21
  ## 1.9.0
8
22
 
9
- Thu, 27 Apr 2023 14:32:16 GMT
23
+ Thu, 27 Apr 2023 14:41:57 GMT
10
24
 
11
25
  ### Minor changes
12
26
 
@@ -39,7 +39,8 @@ const StyledList = /*#__PURE__*/_styledComponents.default.ol.withConfig({
39
39
  listStyle: 'none',
40
40
  listStylePosition: 'inside',
41
41
  margin: 0,
42
- padding: 0
42
+ padding: 0,
43
+ alignItems: 'baseline'
43
44
  });
44
45
 
45
46
  const omitProps = _ref => {
@@ -173,7 +174,9 @@ const Breadcrumbs = _ref2 => {
173
174
  })
174
175
  })
175
176
  });
176
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("nav", { ...selectProps(rest),
177
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("nav", {
178
+ "aria-label": "Breadcrumb",
179
+ ...selectProps(rest),
177
180
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(StyledList, {
178
181
  children: items.map(_ref4 => {
179
182
  let {
@@ -194,7 +197,9 @@ const Breadcrumbs = _ref2 => {
194
197
  itemLinkRouterProps
195
198
  },
196
199
  reactRouterLinkComponent: linkComponent,
197
- variant: variant,
200
+ variant: { ...variant,
201
+ size: 'micro'
202
+ },
198
203
  LinkRouter: ItemLinkRouter
199
204
  }, breadcrumbName);
200
205
  })
@@ -228,6 +228,19 @@ const ContentContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
228
228
  };
229
229
  });
230
230
 
231
+ const StyledCustomContentContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
232
+ displayName: "Footnote__StyledCustomContentContainer",
233
+ componentId: "components-web__sc-1563bo5-8"
234
+ })(_ref11 => {
235
+ let {
236
+ color
237
+ } = _ref11;
238
+ return {
239
+ color,
240
+ fontFamily: 'HelveticaNow400normal'
241
+ };
242
+ });
243
+
231
244
  const usePrevious = value => {
232
245
  const ref = (0, _react.useRef)();
233
246
  (0, _react.useEffect)(() => {
@@ -271,6 +284,7 @@ const Footnote = props => {
271
284
  isOpen,
272
285
  tokens,
273
286
  variant = {},
287
+ dictionary = _dictionary.default,
274
288
  ...rest
275
289
  } = props;
276
290
  const {
@@ -303,7 +317,7 @@ const Footnote = props => {
303
317
  const footnoteRef = (0, _react.useRef)(null);
304
318
  const headerRef = (0, _react.useRef)(null);
305
319
  const bodyRef = (0, _react.useRef)(null);
306
- const listRef = (0, _react.useRef)(null);
320
+ const contentRef = (0, _react.useRef)(null);
307
321
  const headingRef = (0, _react.useRef)(null);
308
322
  const [data, setData] = (0, _react.useState)({
309
323
  content: null,
@@ -314,7 +328,7 @@ const Footnote = props => {
314
328
  const [isVisible, setIsVisible] = (0, _react.useState)(false);
315
329
  const [isTextVisible, setIsTextVisible] = (0, _react.useState)(true);
316
330
  const getCopy = (0, _componentsBase.useCopy)({
317
- dictionary: _dictionary.default,
331
+ dictionary,
318
332
  copy
319
333
  });
320
334
  const prevProps = usePrevious(props);
@@ -345,7 +359,7 @@ const Footnote = props => {
345
359
  }, [closeFootnote]);
346
360
 
347
361
  const saveCurrentHeight = () => {
348
- const oldHeight = listRef.current.offsetHeight;
362
+ const oldHeight = contentRef.current.offsetHeight;
349
363
  setBodyHeight(oldHeight);
350
364
  };
351
365
 
@@ -372,14 +386,14 @@ const Footnote = props => {
372
386
  number
373
387
  });
374
388
 
375
- if (bodyHeight !== listRef.current.offsetHeight) {
389
+ if (bodyHeight !== contentRef.current.offsetHeight) {
376
390
  // Set new height
377
- setBodyHeight(listRef.current.offsetHeight);
391
+ setBodyHeight(contentRef.current.offsetHeight);
378
392
  } else {
379
393
  setIsTextVisible(true);
380
394
  }
381
395
  } else {
382
- setBodyHeight(listRef.current.offsetHeight);
396
+ setBodyHeight(contentRef.current.offsetHeight);
383
397
  }
384
398
 
385
399
  if (event.propertyName === 'height' && !isTextVisible) {
@@ -448,6 +462,35 @@ const Footnote = props => {
448
462
  }, [number, isOpen, prevProps.isOpen, prevProps.number]); // Reset footnote on close
449
463
 
450
464
  (0, _react.useEffect)(resetFootnote, [isOpen]);
465
+ const getFootnoteBodyContent = (0, _react.useCallback)(() => {
466
+ if (!data.number || !data.content) {
467
+ return null;
468
+ }
469
+
470
+ if ( /*#__PURE__*/_react.default.isValidElement(data.content)) {
471
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledCustomContentContainer, {
472
+ ref: contentRef,
473
+ children: data.content
474
+ });
475
+ }
476
+
477
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(List, {
478
+ start: data.number,
479
+ ref: contentRef,
480
+ listPaddingLeft: listPaddingLeft,
481
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ListItem, {
482
+ listItemMarkerFontSize: listItemMarkerFontSize,
483
+ listItemMarkerLineHeight: listItemMarkerLineHeight,
484
+ listItemColor: listItemColor,
485
+ listItemFontSize: listItemFontSize,
486
+ listItemLineHeight: listItemLineHeight,
487
+ listItemPaddingLeft: listItemPaddingLeft,
488
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
489
+ children: (0, _utils.renderStructuredContent)(data.content)
490
+ })
491
+ })
492
+ });
493
+ }, [data.content, data.number, listItemColor, listItemFontSize, listItemLineHeight, listItemMarkerFontSize, listItemMarkerLineHeight, listItemPaddingLeft, listPaddingLeft]);
451
494
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Portal, {
452
495
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { ...selectProps(rest),
453
496
  children: [isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(GlobalBodyScrollLock, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledFootnote, {
@@ -501,22 +544,7 @@ const Footnote = props => {
501
544
  maxWidth: theme.contentMaxWidth,
502
545
  footnoteBodyBackground: footnoteBodyBackground,
503
546
  footnoteBodyPadding: `${footnoteBodyPaddingTop}px ${footnoteBodyPaddingRight}px ${footnoteBodyPaddingBottom}px ${footnoteBodyPaddingLeft}px`,
504
- children: data.number && data.content && /*#__PURE__*/(0, _jsxRuntime.jsx)(List, {
505
- start: data.number,
506
- ref: listRef,
507
- listPaddingLeft: listPaddingLeft,
508
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ListItem, {
509
- listItemMarkerFontSize: listItemMarkerFontSize,
510
- listItemMarkerLineHeight: listItemMarkerLineHeight,
511
- listItemColor: listItemColor,
512
- listItemFontSize: listItemFontSize,
513
- listItemLineHeight: listItemLineHeight,
514
- listItemPaddingLeft: listItemPaddingLeft,
515
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
516
- children: (0, _utils.renderStructuredContent)(data.content)
517
- })
518
- })
519
- })
547
+ children: getFootnoteBodyContent()
520
548
  })]
521
549
  })
522
550
  })]
@@ -527,6 +555,13 @@ const Footnote = props => {
527
555
  const copyShape = _propTypes.default.shape({
528
556
  close: _propTypes.default.string.isRequired,
529
557
  heading: _propTypes.default.string.isRequired
558
+ }); // If a language dictionary entry is provided, it must contain every key
559
+
560
+
561
+ const dictionaryContentShape = _propTypes.default.shape({
562
+ a11yLabel: _propTypes.default.string.isRequired,
563
+ close: _propTypes.default.string.isRequired,
564
+ heading: _propTypes.default.string.isRequired
530
565
  });
531
566
 
532
567
  Footnote.propTypes = { ...selectedSystemPropTypes,
@@ -534,7 +569,7 @@ Footnote.propTypes = { ...selectedSystemPropTypes,
534
569
  /**
535
570
  * The content.
536
571
  */
537
- content: _propTypes.default.string,
572
+ content: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.element]),
538
573
 
539
574
  /**
540
575
  * Use the `copy` prop to either select provided English or French copy by passing 'en' or 'fr' respectively.
@@ -559,7 +594,15 @@ Footnote.propTypes = { ...selectedSystemPropTypes,
559
594
  * @param {Object} options Custom options
560
595
  * @param {boolean} options.returnFocus Should the `Footnote` return focus on close
561
596
  */
562
- onClose: _propTypes.default.func.isRequired
597
+ onClose: _propTypes.default.func.isRequired,
598
+
599
+ /**
600
+ * Override the default dictionary, by passing the complete dictionary object for `en` and `fr`
601
+ */
602
+ dictionary: _propTypes.default.shape({
603
+ en: dictionaryContentShape,
604
+ fr: dictionaryContentShape
605
+ })
563
606
  };
564
607
  Footnote.defaultProps = {
565
608
  isOpen: false,
@@ -34,12 +34,12 @@ const slideDown = property => function (from, to) {
34
34
  return (0, _styledComponents.keyframes)(["0%{", ":", ";}99%{", ":", ";}100%{", ":", ";}"], property, from, property, to, property, end);
35
35
  };
36
36
 
37
- const animation = props => (0, _styledComponents.css)(["", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 3.2s forwards;& *{animation:", " 1s ease-in-out 3s forwards;}& > a div{animation:", " 1s ease-in-out 3s forwards;}& > a svg{animation:", " 1s ease-in-out 3s forwards;}"], slideDown('height')(`${props.animationHeightBefore}px`, `${props.animationHeightAfter}px`, 'auto'), transform('padding-bottom')(`${props.animationPaddingBottomBefore}px`, `${props.animationPaddingBottomAfter}px`), transform('padding-top')(`${props.animationPaddingTopBefore}px`, `${props.animationPaddingTopAfter}px`), transform('background')(props.animationBackgroundColorBefore, props.animationBackgroundColorAfter), transform('color')(props.animationColorBefore, props.animationColorAfter), transform('color')(props.animationDivColorBefore, props.animationDivColorAfter), transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter));
37
+ const animation = props => (0, _styledComponents.css)(["", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 3.2s forwards;& *{animation:", " 1s ease-in-out 3s forwards;}& > a div{animation:", " 1s ease-in-out 3s forwards;}& > a svg{animation:", " 1s ease-in-out 3s forwards;}& > a div{animation:", " 1s ease-in-out 3s forwards;}"], slideDown('height')(`${props.animationHeightBefore}px`, `${props.animationHeightAfter}px`, 'auto'), transform('padding-bottom')(`${props.animationPaddingBottomBefore}px`, `${props.animationPaddingBottomAfter}px`), transform('padding-top')(`${props.animationPaddingTopBefore}px`, `${props.animationPaddingTopAfter}px`), transform('background')(props.animationBackgroundColorBefore, props.animationBackgroundColorAfter), transform('color')(props.animationColorBefore, props.animationColorAfter), transform('color')(props.animationDivColorBefore, props.animationDivColorAfter), transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter), transform('color')(props.animationFillColorBefore, props.animationFillColorAfter));
38
38
 
39
39
  const ToastContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
40
40
  displayName: "Toast__ToastContainer",
41
41
  componentId: "components-web__sc-p78jdh-0"
42
- })(["display:flex;justify-content:center;background:", ";gap:", ";height:0;overflow:hidden;animation:", ";"], _ref => {
42
+ })(["display:flex;justify-content:center;align-items:center;background:", ";gap:", ";height:0;overflow:hidden;animation:", ";"], _ref => {
43
43
  let {
44
44
  containerBackgroundColor
45
45
  } = _ref;
@@ -73,10 +73,17 @@ const Toast = _ref3 => {
73
73
  animationBackgroundColorBefore,
74
74
  animationBackgroundColorAfter,
75
75
  animationColorBefore,
76
- animationColorAfter,
77
- animationFillColorBefore,
78
- animationFillColorAfter
79
- } = (0, _componentsBase.useThemeTokens)('Toast', tokens, variant);
76
+ animationColorAfter
77
+ } = (0, _componentsBase.useThemeTokens)('Toast', tokens, variant); // inherit ChevronLink tokens for animation colors
78
+
79
+ const {
80
+ color: chevronDefaultColor
81
+ } = (0, _componentsBase.useThemeTokens)('ChevronLink', {}, {});
82
+ const {
83
+ color: chevronInverseColor
84
+ } = (0, _componentsBase.useThemeTokens)('ChevronLink', {}, {
85
+ inverse: true
86
+ });
80
87
 
81
88
  if (!toast) {
82
89
  return null;
@@ -95,8 +102,8 @@ const Toast = _ref3 => {
95
102
  animationBackgroundColorAfter: animationBackgroundColorAfter,
96
103
  animationColorBefore: animationColorBefore,
97
104
  animationColorAfter: animationColorAfter,
98
- animationFillColorBefore: animationFillColorBefore,
99
- animationFillColorAfter: animationFillColorAfter,
105
+ animationFillColorBefore: chevronInverseColor,
106
+ animationFillColorAfter: chevronDefaultColor,
100
107
  ...selectProps(rest),
101
108
  children: [headline && /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
102
109
  variant: {
@@ -19,7 +19,8 @@ const StyledList = /*#__PURE__*/styled.ol.withConfig({
19
19
  listStyle: 'none',
20
20
  listStylePosition: 'inside',
21
21
  margin: 0,
22
- padding: 0
22
+ padding: 0,
23
+ alignItems: 'baseline'
23
24
  });
24
25
 
25
26
  const omitProps = _ref => {
@@ -155,7 +156,9 @@ const Breadcrumbs = _ref2 => {
155
156
  })
156
157
  });
157
158
 
158
- return /*#__PURE__*/_jsxs("nav", { ...selectProps(rest),
159
+ return /*#__PURE__*/_jsxs("nav", {
160
+ "aria-label": "Breadcrumb",
161
+ ...selectProps(rest),
159
162
  children: [/*#__PURE__*/_jsx(StyledList, {
160
163
  children: items.map(_ref4 => {
161
164
  let {
@@ -176,7 +179,9 @@ const Breadcrumbs = _ref2 => {
176
179
  itemLinkRouterProps
177
180
  },
178
181
  reactRouterLinkComponent: linkComponent,
179
- variant: variant,
182
+ variant: { ...variant,
183
+ size: 'micro'
184
+ },
180
185
  LinkRouter: ItemLinkRouter
181
186
  }, breadcrumbName);
182
187
  })
@@ -5,7 +5,7 @@ import { Icon, Portal, selectSystemProps, Typography, useCopy, useTheme, useResp
5
5
  import Close from '../../__fixtures__/icons/Close';
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]);
@@ -199,6 +199,18 @@ const ContentContainer = /*#__PURE__*/styled.div.withConfig({
199
199
  width: maxWidth
200
200
  };
201
201
  });
202
+ const StyledCustomContentContainer = /*#__PURE__*/styled.div.withConfig({
203
+ displayName: "Footnote__StyledCustomContentContainer",
204
+ componentId: "components-web__sc-1563bo5-8"
205
+ })(_ref11 => {
206
+ let {
207
+ color
208
+ } = _ref11;
209
+ return {
210
+ color,
211
+ fontFamily: 'HelveticaNow400normal'
212
+ };
213
+ });
202
214
 
203
215
  const usePrevious = value => {
204
216
  const ref = useRef();
@@ -243,6 +255,7 @@ const Footnote = props => {
243
255
  isOpen,
244
256
  tokens,
245
257
  variant = {},
258
+ dictionary = defaultDictionary,
246
259
  ...rest
247
260
  } = props;
248
261
  const {
@@ -275,7 +288,7 @@ const Footnote = props => {
275
288
  const footnoteRef = useRef(null);
276
289
  const headerRef = useRef(null);
277
290
  const bodyRef = useRef(null);
278
- const listRef = useRef(null);
291
+ const contentRef = useRef(null);
279
292
  const headingRef = useRef(null);
280
293
  const [data, setData] = useState({
281
294
  content: null,
@@ -317,7 +330,7 @@ const Footnote = props => {
317
330
  }, [closeFootnote]);
318
331
 
319
332
  const saveCurrentHeight = () => {
320
- const oldHeight = listRef.current.offsetHeight;
333
+ const oldHeight = contentRef.current.offsetHeight;
321
334
  setBodyHeight(oldHeight);
322
335
  };
323
336
 
@@ -344,14 +357,14 @@ const Footnote = props => {
344
357
  number
345
358
  });
346
359
 
347
- if (bodyHeight !== listRef.current.offsetHeight) {
360
+ if (bodyHeight !== contentRef.current.offsetHeight) {
348
361
  // Set new height
349
- setBodyHeight(listRef.current.offsetHeight);
362
+ setBodyHeight(contentRef.current.offsetHeight);
350
363
  } else {
351
364
  setIsTextVisible(true);
352
365
  }
353
366
  } else {
354
- setBodyHeight(listRef.current.offsetHeight);
367
+ setBodyHeight(contentRef.current.offsetHeight);
355
368
  }
356
369
 
357
370
  if (event.propertyName === 'height' && !isTextVisible) {
@@ -420,6 +433,35 @@ const Footnote = props => {
420
433
  }, [number, isOpen, prevProps.isOpen, prevProps.number]); // Reset footnote on close
421
434
 
422
435
  useEffect(resetFootnote, [isOpen]);
436
+ const getFootnoteBodyContent = useCallback(() => {
437
+ if (!data.number || !data.content) {
438
+ return null;
439
+ }
440
+
441
+ if ( /*#__PURE__*/React.isValidElement(data.content)) {
442
+ return /*#__PURE__*/_jsx(StyledCustomContentContainer, {
443
+ ref: contentRef,
444
+ children: data.content
445
+ });
446
+ }
447
+
448
+ return /*#__PURE__*/_jsx(List, {
449
+ start: data.number,
450
+ ref: contentRef,
451
+ listPaddingLeft: listPaddingLeft,
452
+ children: /*#__PURE__*/_jsx(ListItem, {
453
+ listItemMarkerFontSize: listItemMarkerFontSize,
454
+ listItemMarkerLineHeight: listItemMarkerLineHeight,
455
+ listItemColor: listItemColor,
456
+ listItemFontSize: listItemFontSize,
457
+ listItemLineHeight: listItemLineHeight,
458
+ listItemPaddingLeft: listItemPaddingLeft,
459
+ children: /*#__PURE__*/_jsx(Typography, {
460
+ children: renderStructuredContent(data.content)
461
+ })
462
+ })
463
+ });
464
+ }, [data.content, data.number, listItemColor, listItemFontSize, listItemLineHeight, listItemMarkerFontSize, listItemMarkerLineHeight, listItemPaddingLeft, listPaddingLeft]);
423
465
  return /*#__PURE__*/_jsx(Portal, {
424
466
  children: /*#__PURE__*/_jsxs("div", { ...selectProps(rest),
425
467
  children: [isOpen && /*#__PURE__*/_jsx(GlobalBodyScrollLock, {}), /*#__PURE__*/_jsx(StyledFootnote, {
@@ -473,22 +515,7 @@ const Footnote = props => {
473
515
  maxWidth: theme.contentMaxWidth,
474
516
  footnoteBodyBackground: footnoteBodyBackground,
475
517
  footnoteBodyPadding: `${footnoteBodyPaddingTop}px ${footnoteBodyPaddingRight}px ${footnoteBodyPaddingBottom}px ${footnoteBodyPaddingLeft}px`,
476
- children: data.number && data.content && /*#__PURE__*/_jsx(List, {
477
- start: data.number,
478
- ref: listRef,
479
- listPaddingLeft: listPaddingLeft,
480
- children: /*#__PURE__*/_jsx(ListItem, {
481
- listItemMarkerFontSize: listItemMarkerFontSize,
482
- listItemMarkerLineHeight: listItemMarkerLineHeight,
483
- listItemColor: listItemColor,
484
- listItemFontSize: listItemFontSize,
485
- listItemLineHeight: listItemLineHeight,
486
- listItemPaddingLeft: listItemPaddingLeft,
487
- children: /*#__PURE__*/_jsx(Typography, {
488
- children: renderStructuredContent(data.content)
489
- })
490
- })
491
- })
518
+ children: getFootnoteBodyContent()
492
519
  })]
493
520
  })
494
521
  })]
@@ -499,13 +526,19 @@ const Footnote = props => {
499
526
  const copyShape = PropTypes.shape({
500
527
  close: PropTypes.string.isRequired,
501
528
  heading: PropTypes.string.isRequired
529
+ }); // If a language dictionary entry is provided, it must contain every key
530
+
531
+ const dictionaryContentShape = PropTypes.shape({
532
+ a11yLabel: PropTypes.string.isRequired,
533
+ close: PropTypes.string.isRequired,
534
+ heading: PropTypes.string.isRequired
502
535
  });
503
536
  Footnote.propTypes = { ...selectedSystemPropTypes,
504
537
 
505
538
  /**
506
539
  * The content.
507
540
  */
508
- content: PropTypes.string,
541
+ content: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
509
542
 
510
543
  /**
511
544
  * Use the `copy` prop to either select provided English or French copy by passing 'en' or 'fr' respectively.
@@ -530,7 +563,15 @@ Footnote.propTypes = { ...selectedSystemPropTypes,
530
563
  * @param {Object} options Custom options
531
564
  * @param {boolean} options.returnFocus Should the `Footnote` return focus on close
532
565
  */
533
- onClose: PropTypes.func.isRequired
566
+ onClose: PropTypes.func.isRequired,
567
+
568
+ /**
569
+ * Override the default dictionary, by passing the complete dictionary object for `en` and `fr`
570
+ */
571
+ dictionary: PropTypes.shape({
572
+ en: dictionaryContentShape,
573
+ fr: dictionaryContentShape
574
+ })
534
575
  };
535
576
  Footnote.defaultProps = {
536
577
  isOpen: false,
@@ -16,12 +16,12 @@ const slideDown = property => function (from, to) {
16
16
  return keyframes(["0%{", ":", ";}99%{", ":", ";}100%{", ":", ";}"], property, from, property, to, property, end);
17
17
  };
18
18
 
19
- const animation = props => css(["", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 3.2s forwards;& *{animation:", " 1s ease-in-out 3s forwards;}& > a div{animation:", " 1s ease-in-out 3s forwards;}& > a svg{animation:", " 1s ease-in-out 3s forwards;}"], slideDown('height')(`${props.animationHeightBefore}px`, `${props.animationHeightAfter}px`, 'auto'), transform('padding-bottom')(`${props.animationPaddingBottomBefore}px`, `${props.animationPaddingBottomAfter}px`), transform('padding-top')(`${props.animationPaddingTopBefore}px`, `${props.animationPaddingTopAfter}px`), transform('background')(props.animationBackgroundColorBefore, props.animationBackgroundColorAfter), transform('color')(props.animationColorBefore, props.animationColorAfter), transform('color')(props.animationDivColorBefore, props.animationDivColorAfter), transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter));
19
+ const animation = props => css(["", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 2s forwards,", " 1s ease-in-out 3.2s forwards;& *{animation:", " 1s ease-in-out 3s forwards;}& > a div{animation:", " 1s ease-in-out 3s forwards;}& > a svg{animation:", " 1s ease-in-out 3s forwards;}& > a div{animation:", " 1s ease-in-out 3s forwards;}"], slideDown('height')(`${props.animationHeightBefore}px`, `${props.animationHeightAfter}px`, 'auto'), transform('padding-bottom')(`${props.animationPaddingBottomBefore}px`, `${props.animationPaddingBottomAfter}px`), transform('padding-top')(`${props.animationPaddingTopBefore}px`, `${props.animationPaddingTopAfter}px`), transform('background')(props.animationBackgroundColorBefore, props.animationBackgroundColorAfter), transform('color')(props.animationColorBefore, props.animationColorAfter), transform('color')(props.animationDivColorBefore, props.animationDivColorAfter), transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter), transform('color')(props.animationFillColorBefore, props.animationFillColorAfter));
20
20
 
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;background:", ";gap:", ";height:0;overflow:hidden;animation:", ";"], _ref => {
24
+ })(["display:flex;justify-content:center;align-items:center;background:", ";gap:", ";height:0;overflow:hidden;animation:", ";"], _ref => {
25
25
  let {
26
26
  containerBackgroundColor
27
27
  } = _ref;
@@ -55,10 +55,17 @@ const Toast = _ref3 => {
55
55
  animationBackgroundColorBefore,
56
56
  animationBackgroundColorAfter,
57
57
  animationColorBefore,
58
- animationColorAfter,
59
- animationFillColorBefore,
60
- animationFillColorAfter
61
- } = useThemeTokens('Toast', tokens, variant);
58
+ animationColorAfter
59
+ } = useThemeTokens('Toast', tokens, variant); // inherit ChevronLink tokens for animation colors
60
+
61
+ const {
62
+ color: chevronDefaultColor
63
+ } = useThemeTokens('ChevronLink', {}, {});
64
+ const {
65
+ color: chevronInverseColor
66
+ } = useThemeTokens('ChevronLink', {}, {
67
+ inverse: true
68
+ });
62
69
 
63
70
  if (!toast) {
64
71
  return null;
@@ -77,8 +84,8 @@ const Toast = _ref3 => {
77
84
  animationBackgroundColorAfter: animationBackgroundColorAfter,
78
85
  animationColorBefore: animationColorBefore,
79
86
  animationColorAfter: animationColorAfter,
80
- animationFillColorBefore: animationFillColorBefore,
81
- animationFillColorAfter: animationFillColorAfter,
87
+ animationFillColorBefore: chevronInverseColor,
88
+ animationFillColorAfter: chevronDefaultColor,
82
89
  ...selectProps(rest),
83
90
  children: [headline && /*#__PURE__*/_jsx(Typography, {
84
91
  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.38.0",
8
+ "@telus-uds/components-base": "1.39.0",
9
9
  "@telus-uds/system-constants": "^1.2.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.23.0",
15
+ "@telus-uds/system-theme-tokens": "^2.24.0",
16
16
  "prop-types": "^15.7.2",
17
17
  "lodash.throttle": "^4.1.1",
18
18
  "react-youtube": "^10.1.0"
@@ -61,5 +61,5 @@
61
61
  "skip": true
62
62
  },
63
63
  "types": "types/index.d.ts",
64
- "version": "1.9.0"
64
+ "version": "1.10.0"
65
65
  }
@@ -22,7 +22,8 @@ const StyledList = styled.ol({
22
22
  listStyle: 'none',
23
23
  listStylePosition: 'inside',
24
24
  margin: 0,
25
- padding: 0
25
+ padding: 0,
26
+ alignItems: 'baseline'
26
27
  })
27
28
 
28
29
  const omitProps = ({
@@ -149,7 +150,7 @@ const Breadcrumbs = ({
149
150
  )
150
151
 
151
152
  return (
152
- <nav {...selectProps(rest)}>
153
+ <nav aria-label="Breadcrumb" {...selectProps(rest)}>
153
154
  <StyledList>
154
155
  {items.map(
155
156
  ({
@@ -169,7 +170,7 @@ const Breadcrumbs = ({
169
170
  key={href}
170
171
  linkRouterProps={{ ...linkRouterProps, itemLinkRouterProps }}
171
172
  reactRouterLinkComponent={linkComponent}
172
- variant={variant}
173
+ variant={{ ...variant, size: 'micro' }}
173
174
  LinkRouter={ItemLinkRouter}
174
175
  >
175
176
  {breadcrumbName}
@@ -15,7 +15,7 @@ import {
15
15
  import Close from '../../__fixtures__/icons/Close'
16
16
  import OrderedListBase from '../OrderedList/OrderedListBase'
17
17
  import { htmlAttrs, media, renderStructuredContent } from '../utils'
18
- import dictionary from './dictionary'
18
+ import defaultDictionary from './dictionary'
19
19
 
20
20
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
21
21
 
@@ -154,6 +154,10 @@ const ContentContainer = styled.div(
154
154
  })
155
155
  )
156
156
 
157
+ const StyledCustomContentContainer = styled.div(({ color }) => ({
158
+ color,
159
+ fontFamily: 'HelveticaNow400normal'
160
+ }))
157
161
  const usePrevious = (value) => {
158
162
  const ref = useRef()
159
163
  useEffect(() => {
@@ -184,7 +188,17 @@ const usePrevious = (value) => {
184
188
  * - When `Footnote` is closed, focus must return to the initiating element
185
189
  */
186
190
  const Footnote = (props) => {
187
- const { copy, number, content, onClose, isOpen, tokens, variant = {}, ...rest } = props
191
+ const {
192
+ copy,
193
+ number,
194
+ content,
195
+ onClose,
196
+ isOpen,
197
+ tokens,
198
+ variant = {},
199
+ dictionary = defaultDictionary,
200
+ ...rest
201
+ } = props
188
202
  const {
189
203
  footnoteBackground,
190
204
  footnoteBorderTopSizeMd,
@@ -216,7 +230,7 @@ const Footnote = (props) => {
216
230
  const footnoteRef = useRef(null)
217
231
  const headerRef = useRef(null)
218
232
  const bodyRef = useRef(null)
219
- const listRef = useRef(null)
233
+ const contentRef = useRef(null)
220
234
  const headingRef = useRef(null)
221
235
  const [data, setData] = useState({ content: null, number: null })
222
236
  const [headerHeight, setHeaderHeight] = useState('auto')
@@ -265,7 +279,7 @@ const Footnote = (props) => {
265
279
  )
266
280
 
267
281
  const saveCurrentHeight = () => {
268
- const oldHeight = listRef.current.offsetHeight
282
+ const oldHeight = contentRef.current.offsetHeight
269
283
  setBodyHeight(oldHeight)
270
284
  }
271
285
 
@@ -287,14 +301,14 @@ const Footnote = (props) => {
287
301
  event.persist()
288
302
  if (event.propertyName === 'opacity' && !isTextVisible) {
289
303
  setData({ content, number })
290
- if (bodyHeight !== listRef.current.offsetHeight) {
304
+ if (bodyHeight !== contentRef.current.offsetHeight) {
291
305
  // Set new height
292
- setBodyHeight(listRef.current.offsetHeight)
306
+ setBodyHeight(contentRef.current.offsetHeight)
293
307
  } else {
294
308
  setIsTextVisible(true)
295
309
  }
296
310
  } else {
297
- setBodyHeight(listRef.current.offsetHeight)
311
+ setBodyHeight(contentRef.current.offsetHeight)
298
312
  }
299
313
 
300
314
  if (event.propertyName === 'height' && !isTextVisible) {
@@ -359,6 +373,41 @@ const Footnote = (props) => {
359
373
  // Reset footnote on close
360
374
  useEffect(resetFootnote, [isOpen])
361
375
 
376
+ const getFootnoteBodyContent = useCallback(() => {
377
+ if (!data.number || !data.content) {
378
+ return null
379
+ }
380
+ if (React.isValidElement(data.content)) {
381
+ return (
382
+ <StyledCustomContentContainer ref={contentRef}>{data.content}</StyledCustomContentContainer>
383
+ )
384
+ }
385
+ return (
386
+ <List start={data.number} ref={contentRef} listPaddingLeft={listPaddingLeft}>
387
+ <ListItem
388
+ listItemMarkerFontSize={listItemMarkerFontSize}
389
+ listItemMarkerLineHeight={listItemMarkerLineHeight}
390
+ listItemColor={listItemColor}
391
+ listItemFontSize={listItemFontSize}
392
+ listItemLineHeight={listItemLineHeight}
393
+ listItemPaddingLeft={listItemPaddingLeft}
394
+ >
395
+ <Typography>{renderStructuredContent(data.content)}</Typography>
396
+ </ListItem>
397
+ </List>
398
+ )
399
+ }, [
400
+ data.content,
401
+ data.number,
402
+ listItemColor,
403
+ listItemFontSize,
404
+ listItemLineHeight,
405
+ listItemMarkerFontSize,
406
+ listItemMarkerLineHeight,
407
+ listItemPaddingLeft,
408
+ listPaddingLeft
409
+ ])
410
+
362
411
  return (
363
412
  <Portal>
364
413
  <div {...selectProps(rest)}>
@@ -402,20 +451,7 @@ const Footnote = (props) => {
402
451
  footnoteBodyBackground={footnoteBodyBackground}
403
452
  footnoteBodyPadding={`${footnoteBodyPaddingTop}px ${footnoteBodyPaddingRight}px ${footnoteBodyPaddingBottom}px ${footnoteBodyPaddingLeft}px`}
404
453
  >
405
- {data.number && data.content && (
406
- <List start={data.number} ref={listRef} listPaddingLeft={listPaddingLeft}>
407
- <ListItem
408
- listItemMarkerFontSize={listItemMarkerFontSize}
409
- listItemMarkerLineHeight={listItemMarkerLineHeight}
410
- listItemColor={listItemColor}
411
- listItemFontSize={listItemFontSize}
412
- listItemLineHeight={listItemLineHeight}
413
- listItemPaddingLeft={listItemPaddingLeft}
414
- >
415
- <Typography>{renderStructuredContent(data.content)}</Typography>
416
- </ListItem>
417
- </List>
418
- )}
454
+ {getFootnoteBodyContent()}
419
455
  </StyledFootnoteBody>
420
456
  </ContentContainer>
421
457
  </StyledFootnote>
@@ -429,12 +465,19 @@ const copyShape = PropTypes.shape({
429
465
  heading: PropTypes.string.isRequired
430
466
  })
431
467
 
468
+ // If a language dictionary entry is provided, it must contain every key
469
+ const dictionaryContentShape = PropTypes.shape({
470
+ a11yLabel: PropTypes.string.isRequired,
471
+ close: PropTypes.string.isRequired,
472
+ heading: PropTypes.string.isRequired
473
+ })
474
+
432
475
  Footnote.propTypes = {
433
476
  ...selectedSystemPropTypes,
434
477
  /**
435
478
  * The content.
436
479
  */
437
- content: PropTypes.string,
480
+ content: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
438
481
  /**
439
482
  * Use the `copy` prop to either select provided English or French copy by passing 'en' or 'fr' respectively.
440
483
  * To provide your own, pass a JSON object with the keys `heading` and `close`.
@@ -455,7 +498,14 @@ Footnote.propTypes = {
455
498
  * @param {Object} options Custom options
456
499
  * @param {boolean} options.returnFocus Should the `Footnote` return focus on close
457
500
  */
458
- onClose: PropTypes.func.isRequired
501
+ onClose: PropTypes.func.isRequired,
502
+ /**
503
+ * Override the default dictionary, by passing the complete dictionary object for `en` and `fr`
504
+ */
505
+ dictionary: PropTypes.shape({
506
+ en: dictionaryContentShape,
507
+ fr: dictionaryContentShape
508
+ })
459
509
  }
460
510
 
461
511
  Footnote.defaultProps = {
@@ -67,11 +67,16 @@ const animation = (props) => css`
67
67
  animation: ${transform('fill')(props.animationFillColorBefore, props.animationFillColorAfter)}
68
68
  1s ease-in-out 3s forwards;
69
69
  }
70
+ & > a div {
71
+ animation: ${transform('color')(props.animationFillColorBefore, props.animationFillColorAfter)}
72
+ 1s ease-in-out 3s forwards;
73
+ }
70
74
  `
71
75
 
72
76
  const ToastContainer = styled.div`
73
77
  display: flex;
74
78
  justify-content: center;
79
+ align-items: center;
75
80
  background: ${({ containerBackgroundColor }) => containerBackgroundColor};
76
81
  gap: ${({ containerGap }) => containerGap};
77
82
  height: 0;
@@ -92,11 +97,13 @@ const Toast = ({ toast, copy, headline, link, tokens, variant = {}, ...rest }) =
92
97
  animationBackgroundColorBefore,
93
98
  animationBackgroundColorAfter,
94
99
  animationColorBefore,
95
- animationColorAfter,
96
- animationFillColorBefore,
97
- animationFillColorAfter
100
+ animationColorAfter
98
101
  } = useThemeTokens('Toast', tokens, variant)
99
102
 
103
+ // inherit ChevronLink tokens for animation colors
104
+ const { color: chevronDefaultColor } = useThemeTokens('ChevronLink', {}, {})
105
+ const { color: chevronInverseColor } = useThemeTokens('ChevronLink', {}, { inverse: true })
106
+
100
107
  if (!toast) {
101
108
  return null
102
109
  }
@@ -115,8 +122,8 @@ const Toast = ({ toast, copy, headline, link, tokens, variant = {}, ...rest }) =
115
122
  animationBackgroundColorAfter={animationBackgroundColorAfter}
116
123
  animationColorBefore={animationColorBefore}
117
124
  animationColorAfter={animationColorAfter}
118
- animationFillColorBefore={animationFillColorBefore}
119
- animationFillColorAfter={animationFillColorAfter}
125
+ animationFillColorBefore={chevronInverseColor}
126
+ animationFillColorAfter={chevronDefaultColor}
120
127
  {...selectProps(rest)}
121
128
  >
122
129
  {headline && <Typography variant={{ bold: true, inverse: true }}>{headline}</Typography>}