@telus-uds/components-web 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/lib/Breadcrumbs/Breadcrumbs.js +8 -3
  3. package/lib/Breadcrumbs/Item/Item.js +31 -6
  4. package/lib/Callout/Callout.js +24 -3
  5. package/lib/Disclaimer/Disclaimer.js +72 -0
  6. package/lib/Disclaimer/index.js +15 -0
  7. package/lib/Footnote/Footnote.js +70 -28
  8. package/lib/Footnote/FootnoteLink.js +11 -13
  9. package/lib/NavigationBar/NavigationBar.js +231 -0
  10. package/lib/NavigationBar/NavigationItem.js +111 -0
  11. package/lib/NavigationBar/NavigationSubMenu.js +179 -0
  12. package/lib/NavigationBar/collapseItems.js +51 -0
  13. package/lib/NavigationBar/index.js +13 -0
  14. package/lib/PriceLockup/PriceLockup.js +40 -17
  15. package/lib/PriceLockup/tokens.js +49 -116
  16. package/lib/Progress/ProgressBar.js +100 -0
  17. package/lib/Progress/index.js +16 -0
  18. package/lib/Ribbon/Ribbon.js +53 -32
  19. package/lib/Spinner/Spinner.js +18 -14
  20. package/lib/Table/Cell.js +15 -1
  21. package/lib/Toast/Toast.js +15 -8
  22. package/lib/VideoPicker/VideoPicker.js +177 -0
  23. package/lib/VideoPicker/VideoPickerPlayer.js +54 -0
  24. package/lib/VideoPicker/VideoPickerThumbnail.js +201 -0
  25. package/lib/VideoPicker/VideoSlider.js +100 -0
  26. package/lib/VideoPicker/index.js +13 -0
  27. package/lib/VideoPicker/videoPropType.js +25 -0
  28. package/lib/index.js +37 -1
  29. package/lib-module/Breadcrumbs/Breadcrumbs.js +8 -3
  30. package/lib-module/Breadcrumbs/Item/Item.js +32 -7
  31. package/lib-module/Callout/Callout.js +24 -3
  32. package/lib-module/Disclaimer/Disclaimer.js +54 -0
  33. package/lib-module/Disclaimer/index.js +1 -0
  34. package/lib-module/Footnote/Footnote.js +68 -27
  35. package/lib-module/Footnote/FootnoteLink.js +12 -14
  36. package/lib-module/NavigationBar/NavigationBar.js +207 -0
  37. package/lib-module/NavigationBar/NavigationItem.js +87 -0
  38. package/lib-module/NavigationBar/NavigationSubMenu.js +161 -0
  39. package/lib-module/NavigationBar/collapseItems.js +43 -0
  40. package/lib-module/NavigationBar/index.js +2 -0
  41. package/lib-module/PriceLockup/PriceLockup.js +42 -19
  42. package/lib-module/PriceLockup/tokens.js +54 -119
  43. package/lib-module/Progress/ProgressBar.js +83 -0
  44. package/lib-module/Progress/index.js +4 -0
  45. package/lib-module/Ribbon/Ribbon.js +53 -32
  46. package/lib-module/Spinner/Spinner.js +17 -14
  47. package/lib-module/Table/Cell.js +15 -1
  48. package/lib-module/Toast/Toast.js +15 -8
  49. package/lib-module/VideoPicker/VideoPicker.js +151 -0
  50. package/lib-module/VideoPicker/VideoPickerPlayer.js +41 -0
  51. package/lib-module/VideoPicker/VideoPickerThumbnail.js +180 -0
  52. package/lib-module/VideoPicker/VideoSlider.js +83 -0
  53. package/lib-module/VideoPicker/index.js +2 -0
  54. package/lib-module/VideoPicker/videoPropType.js +9 -0
  55. package/lib-module/index.js +4 -0
  56. package/package.json +3 -3
  57. package/src/Breadcrumbs/Breadcrumbs.jsx +4 -3
  58. package/src/Breadcrumbs/Item/Item.jsx +18 -4
  59. package/src/Callout/Callout.jsx +27 -3
  60. package/src/Disclaimer/Disclaimer.jsx +39 -0
  61. package/src/Disclaimer/index.js +1 -0
  62. package/src/Footnote/Footnote.jsx +76 -26
  63. package/src/Footnote/FootnoteLink.jsx +28 -18
  64. package/src/NavigationBar/NavigationBar.jsx +217 -0
  65. package/src/NavigationBar/NavigationItem.jsx +83 -0
  66. package/src/NavigationBar/NavigationSubMenu.jsx +121 -0
  67. package/src/NavigationBar/collapseItems.js +29 -0
  68. package/src/NavigationBar/index.js +3 -0
  69. package/src/PriceLockup/PriceLockup.jsx +47 -21
  70. package/src/PriceLockup/tokens.js +34 -54
  71. package/src/Progress/ProgressBar.jsx +67 -0
  72. package/src/Progress/index.js +6 -0
  73. package/src/Ribbon/Ribbon.jsx +21 -9
  74. package/src/Spinner/Spinner.jsx +20 -17
  75. package/src/Table/Cell.jsx +22 -5
  76. package/src/Toast/Toast.jsx +12 -5
  77. package/src/VideoPicker/VideoPicker.jsx +144 -0
  78. package/src/VideoPicker/VideoPickerPlayer.jsx +21 -0
  79. package/src/VideoPicker/VideoPickerThumbnail.jsx +182 -0
  80. package/src/VideoPicker/VideoSlider.jsx +85 -0
  81. package/src/VideoPicker/index.js +3 -0
  82. package/src/VideoPicker/videoPropType.js +12 -0
  83. package/src/index.js +4 -0
@@ -0,0 +1,151 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { viewports } from '@telus-uds/system-constants';
4
+ import { selectSystemProps, StackView, useThemeTokens, useViewport } from '@telus-uds/components-base';
5
+ import styled, { css } from 'styled-components';
6
+ import { VideoPropType } from './videoPropType';
7
+ import VideoPickerThumbnail from './VideoPickerThumbnail';
8
+ import VideoPickerPlayer from './VideoPickerPlayer';
9
+ import VideoSlider from './VideoSlider';
10
+ import { htmlAttrs } from '../utils';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ import { jsxs as _jsxs } from "react/jsx-runtime";
13
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
14
+
15
+ const framedContainerStyles = _ref => {
16
+ let {
17
+ framedContainerBackgroundColor,
18
+ framedContainerBorderWidth,
19
+ framedContainerBorderColor,
20
+ framedContainerBorderRadius,
21
+ framedMaxHeight
22
+ } = _ref;
23
+ return css(["background-color:", ";border:", "px solid ", ";border-radius:", "px;& > div{max-height:", "px;}"], framedContainerBackgroundColor, framedContainerBorderWidth, framedContainerBorderColor, framedContainerBorderRadius, framedMaxHeight);
24
+ };
25
+
26
+ const VideoPickerContainer = /*#__PURE__*/styled.div.withConfig({
27
+ displayName: "VideoPicker__VideoPickerContainer",
28
+ componentId: "components-web__sc-x6lxp0-0"
29
+ })(["", ""], _ref2 => {
30
+ let {
31
+ isFramed,
32
+ ...tokens
33
+ } = _ref2;
34
+ return isFramed && framedContainerStyles(tokens);
35
+ });
36
+
37
+ const framedPlayerContainerStyles = _ref3 => {
38
+ let {
39
+ framedMaxHeight,
40
+ framedContainerPadding
41
+ } = _ref3;
42
+ return css(["width:66.67%;padding:", "px;max-height:", "px;flex-shrink:0;box-sizing:border-box;"], framedContainerPadding, framedMaxHeight);
43
+ };
44
+
45
+ const VideoPlayerContainer = /*#__PURE__*/styled.div.withConfig({
46
+ displayName: "VideoPicker__VideoPlayerContainer",
47
+ componentId: "components-web__sc-x6lxp0-1"
48
+ })(["", " overflow:auto;"], _ref4 => {
49
+ let {
50
+ isFramed,
51
+ ...tokens
52
+ } = _ref4;
53
+ return isFramed && framedPlayerContainerStyles(tokens);
54
+ });
55
+ const framedVideoListContainerStyle = /*#__PURE__*/css(["max-height:", "px;overflow:auto;flex-direction:column;"], _ref5 => {
56
+ let {
57
+ framedMaxHeight
58
+ } = _ref5;
59
+ return framedMaxHeight;
60
+ });
61
+ const VideoListContainer = /*#__PURE__*/styled.div.withConfig({
62
+ displayName: "VideoPicker__VideoListContainer",
63
+ componentId: "components-web__sc-x6lxp0-2"
64
+ })(["display:flex;justify-content:flex-start;position:relative;flex-grow:1;flex-direction:column;", ""], props => props.isFramed && framedVideoListContainerStyle);
65
+
66
+ const VideoPicker = _ref6 => {
67
+ var _videoList$;
68
+
69
+ let {
70
+ videoList = [],
71
+ selectedVideo = (_videoList$ = videoList[0]) === null || _videoList$ === void 0 ? void 0 : _videoList$.videoId,
72
+ frame,
73
+ ...rest
74
+ } = _ref6;
75
+ const viewport = useViewport();
76
+ const {
77
+ stackViewDividerColor,
78
+ ...themeTokens
79
+ } = useThemeTokens('VideoPicker');
80
+ const [currentVideoId, setCurrentVideoId] = useState(selectedVideo);
81
+ const videoPlayerRef = useRef(null);
82
+ const currentVideo = videoList.find(video => video.videoId === currentVideoId);
83
+ useEffect(() => {
84
+ // Update current video if parent changes which video id it passes down
85
+ setCurrentVideoId(selectedVideo);
86
+ }, [selectedVideo]); // `frame` variant should only work on larger screens
87
+
88
+ const isFramed = frame && [viewports.md, viewports.lg, viewports.xl].includes(viewport);
89
+ const hasSlider = !frame && [viewports.md, viewports.lg, viewports.xl].includes(viewport);
90
+ const listElements = videoList.map((video, index) => /*#__PURE__*/_jsx(VideoPickerThumbnail, {
91
+ video: video,
92
+ videoPlayerRef: videoPlayerRef,
93
+ selectedVideoId: currentVideoId,
94
+ onSelectVideo: current => setCurrentVideoId(current.videoId),
95
+ layout: !hasSlider ? 'horizontal' : 'vertical',
96
+ index: index,
97
+ isFramed: isFramed
98
+ }, video.videoId));
99
+ return /*#__PURE__*/_jsx(VideoPickerContainer, {
100
+ isFramed: isFramed,
101
+ ...selectProps(rest),
102
+ ...themeTokens,
103
+ children: /*#__PURE__*/_jsxs(StackView, {
104
+ divider: isFramed ? {
105
+ tokens: {
106
+ color: stackViewDividerColor
107
+ }
108
+ } : {
109
+ variant: {
110
+ decorative: true
111
+ }
112
+ },
113
+ space: isFramed ? 0 : 4 // everything has internal padding in `frame` variant
114
+ ,
115
+ direction: isFramed ? 'row' : 'column',
116
+ children: [/*#__PURE__*/_jsx(VideoPlayerContainer, { ...themeTokens,
117
+ isFramed: isFramed,
118
+ children: /*#__PURE__*/_jsx(VideoPickerPlayer, {
119
+ video: currentVideo,
120
+ videoPlayerRef: videoPlayerRef
121
+ })
122
+ }), hasSlider ? /*#__PURE__*/_jsx(VideoSlider, {
123
+ children: listElements
124
+ }) : /*#__PURE__*/_jsx(VideoListContainer, {
125
+ viewport: viewport,
126
+ "data-testid": "video-list-container",
127
+ isFramed: isFramed,
128
+ children: listElements
129
+ })]
130
+ })
131
+ });
132
+ };
133
+
134
+ VideoPicker.propTypes = { ...selectedSystemPropTypes,
135
+
136
+ /**
137
+ * Id of the currently selected video (defaults to the first video if not set).
138
+ */
139
+ selectedVideo: PropTypes.string,
140
+
141
+ /**
142
+ * An array of Video objects.
143
+ */
144
+ videoList: PropTypes.arrayOf(VideoPropType),
145
+
146
+ /**
147
+ * Use to display the picker in a container and the playlist as a sidebar (only available for breakpoints LG and larger)
148
+ */
149
+ frame: PropTypes.bool
150
+ };
151
+ export default VideoPicker;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { StackView, Typography } from '@telus-uds/components-base';
3
+ import WebVideo from '../WebVideo/WebVideo';
4
+ import { VideoPropType, RefPropType } from './videoPropType';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+
8
+ const VideoPickerPlayer = _ref => {
9
+ let {
10
+ video = {},
11
+ videoPlayerRef
12
+ } = _ref;
13
+ return /*#__PURE__*/_jsxs(StackView, {
14
+ space: 3,
15
+ tokens: {
16
+ flexShrink: 1
17
+ },
18
+ children: [/*#__PURE__*/_jsx("div", {
19
+ ref: videoPlayerRef,
20
+ children: video.videoId && /*#__PURE__*/_jsx(WebVideo, { ...video
21
+ })
22
+ }), /*#__PURE__*/_jsxs(StackView, {
23
+ space: 2,
24
+ children: [/*#__PURE__*/_jsx(Typography, {
25
+ variant: {
26
+ size: 'h2',
27
+ colour: 'secondary'
28
+ },
29
+ children: video.title
30
+ }), /*#__PURE__*/_jsx(Typography, {
31
+ children: video.description
32
+ })]
33
+ })]
34
+ });
35
+ };
36
+
37
+ VideoPickerPlayer.propTypes = {
38
+ video: VideoPropType,
39
+ videoPlayerRef: RefPropType
40
+ };
41
+ export default VideoPickerPlayer;
@@ -0,0 +1,180 @@
1
+ import React from 'react';
2
+ import Pressable from "react-native-web/dist/exports/Pressable";
3
+ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
4
+ import PropTypes from 'prop-types';
5
+ import { viewports } from '@telus-uds/system-constants';
6
+ import styled from 'styled-components';
7
+ import { StackView, Typography, useViewport, horizontalScrollUtils, useThemeTokens } from '@telus-uds/components-base';
8
+ import { getTimestamp } from '../shared/VideoSplash/helpers';
9
+ import { VideoPropType, RefPropType } from './videoPropType';
10
+ import VideoSplash from '../shared/VideoSplash/VideoSplash';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ import { jsxs as _jsxs } from "react/jsx-runtime";
13
+ const {
14
+ getItemPositionLayoutHandler,
15
+ itemPositionsPropType
16
+ } = horizontalScrollUtils; // Use a React Native (web) outer container so it can take an onLayout callback, to
17
+ // access position in VideoSlider's UDS HorizontalScroll and update its itemPositions
18
+
19
+ const createReactNativeStyles = _ref => {
20
+ let {
21
+ pressablePaddingBottom,
22
+ pressablePaddingVertical,
23
+ pressablePaddingHorizontal,
24
+ pressableBorderTopWidth,
25
+ pressableBorderTopColor
26
+ } = _ref;
27
+ return StyleSheet.create({
28
+ container: {
29
+ cursor: 'pointer'
30
+ },
31
+ horizontal: {
32
+ paddingBottom: pressablePaddingBottom
33
+ },
34
+ framed: {
35
+ paddingVertical: pressablePaddingVertical,
36
+ paddingHorizontal: pressablePaddingHorizontal
37
+ },
38
+ framedLine: {
39
+ borderTopWidth: pressableBorderTopWidth,
40
+ borderTopColor: pressableBorderTopColor
41
+ }
42
+ });
43
+ };
44
+
45
+ const VideoThumbnail = /*#__PURE__*/styled.div.withConfig({
46
+ displayName: "VideoPickerThumbnail__VideoThumbnail",
47
+ componentId: "components-web__sc-1glxurq-0"
48
+ })(["position:relative;width:", ";flex-shrink:0;* button{display:none;}&::before{content:'';display:block;padding-bottom:56.25%;}&::after{content:'';border:", "px solid;border-color:", ";border-radius:", "px;position:absolute;top:0;left:0;right:0;bottom:0;}& > div{border-radius:", "px;}"], props => props.layout === 'vertical' ? '100%' : '144px', _ref2 => {
49
+ let {
50
+ borderWidth
51
+ } = _ref2;
52
+ return borderWidth;
53
+ }, _ref3 => {
54
+ let {
55
+ isPlaying,
56
+ borderColor
57
+ } = _ref3;
58
+ return isPlaying ? borderColor : 'transparent';
59
+ }, _ref4 => {
60
+ let {
61
+ borderRadius
62
+ } = _ref4;
63
+ return borderRadius;
64
+ }, _ref5 => {
65
+ let {
66
+ borderRadius
67
+ } = _ref5;
68
+ return borderRadius;
69
+ });
70
+ const ThumbnailTitleContainer = /*#__PURE__*/styled.div.withConfig({
71
+ displayName: "VideoPickerThumbnail__ThumbnailTitleContainer",
72
+ componentId: "components-web__sc-1glxurq-1"
73
+ })(["display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;"]);
74
+
75
+ const VideoPickerThumbnail = _ref6 => {
76
+ let {
77
+ videoPlayerRef,
78
+ selectedVideoId,
79
+ video,
80
+ onSelectVideo,
81
+ layout = 'vertical',
82
+ isFramed,
83
+ itemPositions,
84
+ index,
85
+ width = '100%'
86
+ } = _ref6;
87
+ const viewport = useViewport();
88
+ const {
89
+ titleColor,
90
+ subTitleColor,
91
+ ...themeTokens
92
+ } = useThemeTokens('VideoPickerThumbnail');
93
+ const rnStyles = createReactNativeStyles(themeTokens);
94
+ const {
95
+ timestamp
96
+ } = getTimestamp(video.videoLength, video.copy);
97
+ const isPlaying = selectedVideoId === video.videoId;
98
+
99
+ const renderThumbnailImage = () => /*#__PURE__*/_jsx(VideoThumbnail, { ...themeTokens,
100
+ isPlaying: isPlaying,
101
+ layout: layout,
102
+ children: /*#__PURE__*/_jsx(VideoSplash, {
103
+ simpleMode: true,
104
+ poster: video.posterSrc || `https://img.youtube.com/vi/${video.videoId}/maxresdefault.jpg`,
105
+ videoLength: video.videoLength,
106
+ copy: video.copy
107
+ })
108
+ });
109
+
110
+ const renderThumbnailInfo = () => /*#__PURE__*/_jsxs(StackView, {
111
+ space: 2,
112
+ tokens: {
113
+ flexShrink: 1
114
+ },
115
+ children: [/*#__PURE__*/_jsx(ThumbnailTitleContainer, {
116
+ viewport: viewport,
117
+ children: /*#__PURE__*/_jsx(Typography, {
118
+ variant: {
119
+ bold: true
120
+ },
121
+ tokens: {
122
+ color: isPlaying ? titleColor : 'none'
123
+ },
124
+ children: video.title
125
+ })
126
+ }), viewport !== viewports.xs && /*#__PURE__*/_jsx(Typography, {
127
+ variant: {
128
+ size: 'micro'
129
+ },
130
+ tokens: {
131
+ color: subTitleColor
132
+ },
133
+ children: timestamp
134
+ })]
135
+ });
136
+
137
+ const handleLayout = itemPositions !== undefined ? getItemPositionLayoutHandler(itemPositions.positions, index) : undefined;
138
+
139
+ const onKeyPress = event => {
140
+ if (['Space', 'Enter'].includes(event.key)) {
141
+ var _videoPlayerRef$curre;
142
+
143
+ onSelectVideo(video);
144
+ const splashButton = (_videoPlayerRef$curre = videoPlayerRef.current) === null || _videoPlayerRef$curre === void 0 ? void 0 : _videoPlayerRef$curre.querySelector('button');
145
+ if (splashButton) splashButton.focus();
146
+ }
147
+ };
148
+
149
+ return /*#__PURE__*/_jsx(Pressable, {
150
+ onLayout: handleLayout,
151
+ onPress: () => onSelectVideo(video),
152
+ testID: `thumbnail-container-${video.videoId}`,
153
+ onKeyPress: onKeyPress,
154
+ accessibilityRole: "radio",
155
+ accessibilityState: {
156
+ checked: isPlaying
157
+ },
158
+ style: [rnStyles.container, layout === 'horizontal' && rnStyles.horizontal, isFramed && rnStyles.framed, isFramed && index > 0 && rnStyles.framedLine, {
159
+ width
160
+ }],
161
+ children: /*#__PURE__*/_jsxs(StackView, {
162
+ space: layout === 'vertical' ? 2 : 3,
163
+ direction: layout === 'vertical' ? 'column' : 'row',
164
+ children: [renderThumbnailImage(), renderThumbnailInfo()]
165
+ })
166
+ }, video.videoId);
167
+ };
168
+
169
+ VideoPickerThumbnail.propTypes = {
170
+ selectedVideoId: PropTypes.string,
171
+ onSelectVideo: PropTypes.func,
172
+ video: VideoPropType,
173
+ videoPlayerRef: RefPropType,
174
+ layout: PropTypes.oneOf(['vertical', 'horizontal']),
175
+ isFramed: PropTypes.bool,
176
+ itemPositions: itemPositionsPropType,
177
+ index: PropTypes.number,
178
+ width: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
179
+ };
180
+ export default VideoPickerThumbnail;
@@ -0,0 +1,83 @@
1
+ import React, { cloneElement, useState } from 'react';
2
+ import { HorizontalScroll, HorizontalScrollButton, horizontalScrollUtils, StackView, useThemeTokens, useViewport } from '@telus-uds/components-base';
3
+ import View from "react-native-web/dist/exports/View";
4
+ import PropTypes from 'prop-types';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const {
7
+ useItemPositions
8
+ } = horizontalScrollUtils;
9
+
10
+ const VideoSlider = _ref => {
11
+ let {
12
+ children
13
+ } = _ref;
14
+ const viewport = useViewport();
15
+ const [itemPositions] = useItemPositions();
16
+ const [containerWidth, setContainerWidth] = useState(null);
17
+ const {
18
+ previousIcon: PreviousIcon,
19
+ nextIcon: NextIcon
20
+ } = useThemeTokens('VideoPickerSlider');
21
+
22
+ const onLayout = _ref2 => {
23
+ let {
24
+ nativeEvent: {
25
+ layout: {
26
+ width
27
+ }
28
+ }
29
+ } = _ref2;
30
+ setContainerWidth(width);
31
+ };
32
+
33
+ const itemsGap = 24; // '4' on spacing scale
34
+
35
+ const itemsCount = viewport === 'lg' || viewport === 'xl' ? 4 : 3;
36
+ const itemGapPortioned = (itemsCount - 1) * itemsGap / itemsCount;
37
+ const itemWidth = containerWidth === null ? // For first render, we don't know container width, so avoid flicker with static % width
38
+ `calc(${Math.round(100 / itemsCount)}% - ${Math.round(itemGapPortioned)}px)` : // After first render, can't use % widths because parent is > 100% width horizontal scroll area
39
+ Math.max(containerWidth / itemsCount - itemGapPortioned, 0 // Prevent negative width breaking layout on very narrow containers
40
+ );
41
+
42
+ const content = /*#__PURE__*/_jsx(StackView, {
43
+ space: 4,
44
+ direction: "row",
45
+ accessibilityRole: "radiogroup",
46
+ tokens: {
47
+ flexGrow: 1
48
+ },
49
+ children: React.Children.map(children, (child, index) => /*#__PURE__*/cloneElement(child, {
50
+ index,
51
+ itemPositions,
52
+ width: itemWidth
53
+ }))
54
+ });
55
+
56
+ const overflow = containerWidth === null && {
57
+ overflow: 'hidden'
58
+ };
59
+ const horizontalScrollTokens = {
60
+ nextIcon: NextIcon,
61
+ previousIcon: PreviousIcon,
62
+ gutter: 0,
63
+ borderBottomWidth: 0,
64
+ borderBottomColor: 'transparent',
65
+ buttonClearance: 0
66
+ };
67
+ return /*#__PURE__*/_jsx(View, {
68
+ onLayout: onLayout,
69
+ style: overflow,
70
+ children: containerWidth === null ? // Use a 100% width non-scrollable parent until containerWidth is known, to avoid flicker
71
+ content : /*#__PURE__*/_jsx(HorizontalScroll, {
72
+ ScrollButton: HorizontalScrollButton,
73
+ itemPositions: itemPositions,
74
+ tokens: horizontalScrollTokens,
75
+ children: content
76
+ })
77
+ });
78
+ };
79
+
80
+ VideoSlider.propTypes = {
81
+ children: PropTypes.node
82
+ };
83
+ export default VideoSlider;
@@ -0,0 +1,2 @@
1
+ import VideoPicker from './VideoPicker';
2
+ export default VideoPicker;
@@ -0,0 +1,9 @@
1
+ import PropTypes from 'prop-types';
2
+ import { VideoProps } from '../WebVideo/WebVideo';
3
+ export const VideoPropType = PropTypes.shape({ ...VideoProps,
4
+ title: PropTypes.string,
5
+ description: PropTypes.string
6
+ });
7
+ export const RefPropType = PropTypes.shape({
8
+ current: PropTypes.object
9
+ });
@@ -27,8 +27,12 @@ export { default as WebVideo } from './WebVideo';
27
27
  export { default as WaffleGrid } from './WaffleGrid';
28
28
  export { default as Spinner } from './Spinner';
29
29
  export { default as Listbox } from './Listbox';
30
+ export { default as VideoPicker } from './VideoPicker';
30
31
  export { default as Video } from './Video';
31
32
  export { default as StoryCard } from './StoryCard';
33
+ export { default as Disclaimer } from './Disclaimer';
32
34
  export { default as Card } from './Card';
33
35
  export { default as TermsAndConditions } from './TermsAndConditions';
36
+ export { default as NavigationBar } from './NavigationBar';
37
+ export { default as Progress } from './Progress';
34
38
  export * from './baseExports';
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.40.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.25.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.11.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}
@@ -4,6 +4,7 @@ import styled from 'styled-components'
4
4
  import {
5
5
  Link,
6
6
  Typography,
7
+ applyTextStyles,
7
8
  clickProps,
8
9
  selectSystemProps,
9
10
  useThemeTokens,
@@ -22,7 +23,8 @@ const IconContainer = styled.span({
22
23
  display: 'inline-flex',
23
24
  alignItems: 'center',
24
25
  paddingLeft: ({ iconPadding }) => `${iconPadding}px`,
25
- paddingRight: ({ iconPadding }) => `${iconPadding}px`
26
+ paddingRight: ({ iconPadding }) => `${iconPadding}px`,
27
+ fontFamily: ({ fontName, fontWeight }) => applyTextStyles({ fontName, fontWeight }).fontFamily
26
28
  })
27
29
 
28
30
  const Item = forwardRef(
@@ -41,6 +43,10 @@ const Item = forwardRef(
41
43
  const {
42
44
  iconColor,
43
45
  icon: ChevronRightIcon,
46
+ currentColor,
47
+ color,
48
+ iconSize,
49
+ fontSize,
44
50
  ...themeTokens
45
51
  } = useThemeTokens('Breadcrumbs', tokens, variant)
46
52
 
@@ -55,12 +61,15 @@ const Item = forwardRef(
55
61
  return (
56
62
  <StyledItemContainer {...themeTokens}>
57
63
  {current ? (
58
- <Typography variant={{ ...variant, secondary: true }}>{children}</Typography>
64
+ <Typography tokens={{ color: currentColor, fontSize }} variant={{ ...variant }}>
65
+ {children}
66
+ </Typography>
59
67
  ) : (
60
68
  <>
61
69
  {ReactRouterLink ? (
62
70
  <ReactRouterLink
63
71
  {...linkOptions}
72
+ tokens={{ color, blockFontSize: fontSize }}
64
73
  // TODO refactor
65
74
  // eslint-disable-next-line react/no-unstable-nested-components
66
75
  component={(props) => {
@@ -71,12 +80,17 @@ const Item = forwardRef(
71
80
  {children}
72
81
  </ReactRouterLink>
73
82
  ) : (
74
- <Link {...linkOptions} ref={ref} variant={variant}>
83
+ <Link
84
+ {...linkOptions}
85
+ tokens={{ color, blockFontSize: fontSize }}
86
+ ref={ref}
87
+ variant={variant}
88
+ >
75
89
  {children}
76
90
  </Link>
77
91
  )}
78
92
  <IconContainer {...themeTokens}>
79
- <ChevronRightIcon size={16} color={iconColor} />
93
+ <ChevronRightIcon size={iconSize} color={iconColor} />
80
94
  </IconContainer>
81
95
  </>
82
96
  )}
@@ -7,6 +7,20 @@ import { htmlAttrs } from '../utils'
7
7
 
8
8
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
9
9
 
10
+ const getAlignment = (rounded, textAlignToFlex) => {
11
+ if (textAlignToFlex) {
12
+ switch (textAlignToFlex) {
13
+ case 'left':
14
+ return 'flex-star'
15
+ case 'center':
16
+ return 'center'
17
+ default:
18
+ return 'flex-start'
19
+ }
20
+ }
21
+ return rounded ? 'center' : ' flex-start'
22
+ }
23
+
10
24
  const verticalAlignToFlex = (verticalAlign) => {
11
25
  switch (verticalAlign) {
12
26
  case 'top':
@@ -21,18 +35,26 @@ const verticalAlignToFlex = (verticalAlign) => {
21
35
  }
22
36
 
23
37
  const CalloutContainer = styled.div(
24
- ({ rounded, verticalAlign = 'top', background, gap, borderRadius, padding }) => ({
38
+ ({ rounded, verticalAlign, textAlignToFlex, background, gap, borderRadius, padding }) => ({
25
39
  background,
26
40
  display: 'flex',
27
41
  gap,
28
42
  borderRadius,
29
43
  padding,
30
- justifyContent: `${rounded ? 'center' : 'flex-start'}`,
44
+ justifyContent: getAlignment(rounded, textAlignToFlex),
31
45
  alignItems: verticalAlignToFlex(verticalAlign)
32
46
  })
33
47
  )
34
48
 
35
- const Callout = ({ icon, children, verticalAlign = 'top', tokens, variant = {}, ...rest }) => {
49
+ const Callout = ({
50
+ icon,
51
+ children,
52
+ verticalAlign,
53
+ textAlignToFlex,
54
+ tokens,
55
+ variant = {},
56
+ ...rest
57
+ }) => {
36
58
  const {
37
59
  background,
38
60
  gap,
@@ -52,6 +74,7 @@ const Callout = ({ icon, children, verticalAlign = 'top', tokens, variant = {},
52
74
  rounded={rounded}
53
75
  data-testid="callout-container"
54
76
  verticalAlign={verticalAlign}
77
+ textAlignToFlex={textAlignToFlex}
55
78
  background={background}
56
79
  gap={gap}
57
80
  borderRadius={borderRadius}
@@ -70,6 +93,7 @@ Callout.propTypes = {
70
93
  ...selectedSystemPropTypes,
71
94
  icon: PropTypes.elementType,
72
95
  children: PropTypes.node.isRequired,
96
+ textAlignToFlex: PropTypes.oneOf(['center', 'left']),
73
97
  verticalAlign: PropTypes.oneOf(['top', 'middle', 'bottom'])
74
98
  }
75
99