@telus-uds/components-web 2.12.0 → 2.13.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 (50) hide show
  1. package/CHANGELOG.md +22 -2
  2. package/component-docs.json +59 -24
  3. package/lib/Autocomplete/Loading.js +5 -10
  4. package/lib/Autocomplete/dictionary.js +2 -2
  5. package/lib/DatePicker/DatePicker.js +6 -0
  6. package/lib/NavigationBar/NavigationSubMenu.js +4 -8
  7. package/lib/Spinner/Spinner.js +10 -1
  8. package/lib/Spinner/SpinnerContent.js +8 -0
  9. package/lib/Table/Cell.js +62 -91
  10. package/lib/Table/Header.js +4 -1
  11. package/lib/Table/SubHeading.js +4 -1
  12. package/lib/Table/Table.js +2 -1
  13. package/lib/TermsAndConditions/ExpandCollapse.js +31 -13
  14. package/lib/TermsAndConditions/TermsAndConditions.js +21 -6
  15. package/lib/VideoPicker/VideoPickerPlayer.js +4 -2
  16. package/lib/VideoPicker/VideoPickerThumbnail.js +103 -60
  17. package/lib/VideoPicker/VideoSlider.js +2 -2
  18. package/lib-module/Autocomplete/Loading.js +6 -12
  19. package/lib-module/Autocomplete/dictionary.js +2 -2
  20. package/lib-module/DatePicker/DatePicker.js +7 -1
  21. package/lib-module/NavigationBar/NavigationSubMenu.js +5 -9
  22. package/lib-module/Spinner/Spinner.js +10 -1
  23. package/lib-module/Spinner/SpinnerContent.js +8 -0
  24. package/lib-module/Table/Cell.js +65 -90
  25. package/lib-module/Table/Header.js +4 -1
  26. package/lib-module/Table/SubHeading.js +4 -1
  27. package/lib-module/Table/Table.js +2 -1
  28. package/lib-module/TermsAndConditions/ExpandCollapse.js +33 -15
  29. package/lib-module/TermsAndConditions/TermsAndConditions.js +22 -7
  30. package/lib-module/VideoPicker/VideoPickerPlayer.js +4 -2
  31. package/lib-module/VideoPicker/VideoPickerThumbnail.js +103 -61
  32. package/lib-module/VideoPicker/VideoSlider.js +2 -2
  33. package/package.json +3 -3
  34. package/src/Autocomplete/Loading.jsx +2 -5
  35. package/src/Autocomplete/dictionary.js +2 -2
  36. package/src/DatePicker/DatePicker.jsx +8 -1
  37. package/src/NavigationBar/NavigationSubMenu.jsx +3 -4
  38. package/src/Spinner/Spinner.jsx +9 -1
  39. package/src/Spinner/SpinnerContent.jsx +13 -1
  40. package/src/Table/Cell.jsx +58 -78
  41. package/src/Table/Header.jsx +6 -1
  42. package/src/Table/SubHeading.jsx +4 -1
  43. package/src/Table/Table.jsx +10 -2
  44. package/src/TermsAndConditions/ExpandCollapse.jsx +36 -14
  45. package/src/TermsAndConditions/TermsAndConditions.jsx +18 -6
  46. package/src/VideoPicker/VideoPickerPlayer.jsx +2 -2
  47. package/src/VideoPicker/VideoPickerThumbnail.jsx +51 -30
  48. package/src/VideoPicker/VideoSlider.jsx +2 -2
  49. package/types/BaseProvider.d.ts +25 -0
  50. package/types/index.d.ts +1 -1
@@ -36,7 +36,15 @@ export const useTableContext = () => useContext(TableContext)
36
36
  * - Use `Table.Row` and `Table.Cell` to build up the tabular data
37
37
  * - Use `Cell`'s `type` prop to visually mark it as a row heading (`type="rowHeading"`)
38
38
  */
39
- const Table = ({ children, fullWidth = true, text = 'medium', tokens, variant, ...rest }) => {
39
+ const Table = ({
40
+ children,
41
+ spacing = 'default',
42
+ fullWidth = true,
43
+ text = 'medium',
44
+ tokens,
45
+ variant,
46
+ ...rest
47
+ }) => {
40
48
  const { tablePaddingBottom } = useThemeTokens('Table', tokens, variant)
41
49
  const containerRef = useRef()
42
50
  const tableRef = useRef()
@@ -75,7 +83,7 @@ const Table = ({ children, fullWidth = true, text = 'medium', tokens, variant, .
75
83
  tablePaddingBottom={`${tablePaddingBottom}px`}
76
84
  {...selectProps(rest)}
77
85
  >
78
- <TableContext.Provider value={{ text, isScrollable, tokens, variant }}>
86
+ <TableContext.Provider value={{ text, isScrollable, tokens, spacing }}>
79
87
  <StyledTable tableWidth={tableWidth} cellSpacing={0} ref={tableRef}>
80
88
  {children}
81
89
  </StyledTable>
@@ -1,8 +1,8 @@
1
- import React, { forwardRef } from 'react'
1
+ import React, { forwardRef, useState } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import {
4
4
  ExpandCollapse as ExpandCollapseBase,
5
- Icon,
5
+ IconButton,
6
6
  useThemeTokensCallback
7
7
  } from '@telus-uds/components-base'
8
8
  import styled from 'styled-components'
@@ -17,18 +17,15 @@ const ExpandCollapseControl = styled.div({
17
17
 
18
18
  const ExpandCollapseIconContainer = styled.div(({ tokens }) => ({
19
19
  alignItems: tokens.expandIconContainerAlignItems,
20
- border: `${tokens.expandIconContainerBorder}px solid ${tokens.expandIconContainerBorderColor}`,
21
- borderRadius: '50%',
22
- display: 'flex',
23
- height: tokens.expandIconContainerHeight,
24
20
  justifyContent: tokens.expandIconContainerJustifyContent,
25
- margin: `${tokens.expandIconContainerMarginX}px ${tokens.expandIconContainerMarginY}px`,
21
+ marginLeft: `${tokens.expandIconContainerMarginY}px`,
22
+ marginRight: `${tokens.expandIconContainerMarginY}px`,
26
23
  width: tokens.expandIconContainerWidth
27
24
  }))
28
25
 
29
26
  const ExpandCollapseTitle = styled.h4(({ tokens }) => ({
30
27
  color: tokens.expandTitleColor,
31
- fontFamily: `${tokens.listFontName}${tokens.listFontWeight}normal`,
28
+ fontFamily: `${tokens.expandTitleFontName}${tokens.expandTitleFontWeight}normal`,
32
29
  fontSize: tokens.expandTitleFontSize,
33
30
  lineHeight: tokens.expandTitleLineHeight,
34
31
  margin: `${tokens.expandTitleMarginX}px ${tokens.expandTitleMarginY}px`
@@ -42,8 +39,20 @@ const ExpandCollapse = forwardRef(
42
39
  expandContentPaddingBottom,
43
40
  expandContentPaddingLeft,
44
41
  expandContentPaddingRight,
45
- expandContentPaddingTop
42
+ expandContentPaddingTop,
43
+ contentBorderColor,
44
+ contentMarginBottom,
45
+ expandTitlePaddingLeft,
46
+ expandTitleBorder,
47
+ expandTitleBorderColor,
48
+ expandTitleUnderline
46
49
  } = getTokens()
50
+ const [expand, setExpand] = useState(false)
51
+
52
+ const handleExpandToggle = (expandProps, event, expanded) => {
53
+ expandProps.onToggle('ExpandCollapsePanel', event)
54
+ setExpand(!expanded)
55
+ }
47
56
 
48
57
  return (
49
58
  <ExpandCollapseBase
@@ -55,7 +64,14 @@ const ExpandCollapse = forwardRef(
55
64
  <ExpandCollapseBase.Panel
56
65
  {...expandProps}
57
66
  panelId="ExpandCollapsePanel"
58
- controlTokens={{ icon: null }}
67
+ controlTokens={{
68
+ icon: null,
69
+ backgroundColor: 'transparent',
70
+ paddingLeft: expandTitlePaddingLeft,
71
+ borderColor: expandTitleBorderColor,
72
+ borderWidth: expandTitleBorder,
73
+ textLine: expandTitleUnderline
74
+ }}
59
75
  // TODO refactor
60
76
  // eslint-disable-next-line react/no-unstable-nested-components
61
77
  control={(pressableState) => {
@@ -64,11 +80,15 @@ const ExpandCollapse = forwardRef(
64
80
 
65
81
  return (
66
82
  <ExpandCollapseControl
67
- onClick={(event) => expandProps.onToggle('ExpandCollapsePanel', event)}
83
+ onClick={(event) => handleExpandToggle(expandProps, event, expanded)}
68
84
  ref={ref}
69
85
  >
70
86
  <ExpandCollapseIconContainer tokens={getTokens()}>
71
- <Icon icon={icon} variant={{ size: 'small' }} />
87
+ <IconButton
88
+ icon={icon}
89
+ variant={{ size: 'small' }}
90
+ onClick={(event) => handleExpandToggle(expandProps, event, expanded)}
91
+ />
72
92
  </ExpandCollapseIconContainer>
73
93
  <ExpandCollapseTitle tokens={getTokens()}>
74
94
  {expanded ? expandTitle : collapseTitle}
@@ -80,10 +100,12 @@ const ExpandCollapse = forwardRef(
80
100
  contentPaddingBottom: expandContentPaddingBottom,
81
101
  contentPaddingLeft: expandContentPaddingLeft,
82
102
  contentPaddingRight: expandContentPaddingRight,
83
- contentPaddingTop: expandContentPaddingTop
103
+ contentPaddingTop: expandContentPaddingTop,
104
+ borderColor: contentBorderColor,
105
+ marginBottom: contentMarginBottom
84
106
  }}
85
107
  >
86
- {children}
108
+ {expand ? children : null}
87
109
  </ExpandCollapseBase.Panel>
88
110
  )}
89
111
  </ExpandCollapseBase>
@@ -7,7 +7,8 @@ import {
7
7
  selectSystemProps,
8
8
  Typography,
9
9
  useCopy,
10
- useThemeTokens
10
+ useThemeTokens,
11
+ useViewport
11
12
  } from '@telus-uds/components-base'
12
13
  import ExpandCollapse from './ExpandCollapse'
13
14
  import OrderedListBase from '../OrderedList/OrderedListBase'
@@ -33,7 +34,8 @@ const Ordered = styled(OrderedListBase)(({ tokens }) => ({
33
34
  const Unordered = styled.ul(({ tokens }) => ({
34
35
  listStyleType: 'none',
35
36
  margin: 0,
36
- padding: tokens.unorderedPadding
37
+ padding: 0,
38
+ paddingTop: tokens.unorderedPadding
37
39
  }))
38
40
 
39
41
  const ListItem = styled(OrderedListBase.Item)(({ tokens }) => ({
@@ -75,11 +77,12 @@ const TermsAndConditions = forwardRef(
75
77
  const hasIndexedContent = indexedContent.length > 0
76
78
  const hasNonIndexedContent = nonIndexedContent.length > 0
77
79
 
78
- const themeTokens = useThemeTokens('TermsAndConditions', tokens, variant)
80
+ const viewport = useViewport()
81
+ const themeTokens = useThemeTokens('TermsAndConditions', tokens, variant, { viewport })
79
82
 
80
83
  return (
81
84
  <div {...selectProps(rest)}>
82
- <Divider />
85
+ <Divider tokens={{ color: themeTokens.dividerColor }} />
83
86
  <ExpandCollapse
84
87
  collapseTitle={getCopy('headingView')}
85
88
  expandTitle={getCopy('headingHide')}
@@ -99,7 +102,16 @@ const TermsAndConditions = forwardRef(
99
102
  {hasNonIndexedContent && (
100
103
  <Box between={3}>
101
104
  <NonIndexedContentTitle tokens={themeTokens}>
102
- <Typography block heading variant={{ size: 'h4' }}>
105
+ <Typography
106
+ block
107
+ heading
108
+ tokens={{
109
+ fontName: themeTokens.expandTitleFontName,
110
+ fontWeight: themeTokens.expandTitleFontWeight,
111
+ fontSize: themeTokens.titleFontSize,
112
+ lineHeight: themeTokens.titleLineHeight
113
+ }}
114
+ >
103
115
  {getCopy('nonIndexedTitle')}
104
116
  </Typography>
105
117
  </NonIndexedContentTitle>
@@ -115,7 +127,7 @@ const TermsAndConditions = forwardRef(
115
127
  )}
116
128
  </ContentContainer>
117
129
  </ExpandCollapse>
118
- <Divider />
130
+ <Divider tokens={{ color: themeTokens.dividerColor }} />
119
131
  </div>
120
132
  )
121
133
  }
@@ -10,8 +10,8 @@ const VideoPickerPlayer = ({ video = {}, videoPlayerRef, onStartVideo = () => {}
10
10
  {video.videoId && <WebVideo {...video} onStart={() => onStartVideo(video)} />}
11
11
  </div>
12
12
  <StackView space={2}>
13
- <Typography variant={{ size: 'h2', colour: 'secondary' }}>{video.title}</Typography>
14
- <Typography>{video.description}</Typography>
13
+ <Typography variant={{ size: 'h3' }}>{video.title}</Typography>
14
+ <Typography variant={{ colour: 'default' }}>{video.description}</Typography>
15
15
  </StackView>
16
16
  </StackView>
17
17
  )
@@ -8,7 +8,7 @@ import {
8
8
  Typography,
9
9
  useViewport,
10
10
  horizontalScrollUtils,
11
- useThemeTokens
11
+ useThemeTokensCallback
12
12
  } from '@telus-uds/components-base'
13
13
  import { getTimestamp } from '../shared/VideoSplash/helpers'
14
14
  import { VideoPropType, RefPropType } from './videoPropType'
@@ -42,6 +42,12 @@ const createReactNativeStyles = ({
42
42
  }
43
43
  })
44
44
 
45
+ const ImageContainer = styled.div`
46
+ padding: ${(props) => `${props.outerBorderGap}px`};
47
+ border: ${(props) => `${props.outerBorderWidth}px solid ${props.outerBorderColor}`};
48
+ border-radius: ${({ outerBorderRadius }) => outerBorderRadius}px;
49
+ `
50
+
45
51
  const VideoThumbnail = styled.div`
46
52
  position: relative;
47
53
  width: ${(props) => (props.layout === 'vertical' ? '100%' : '144px')};
@@ -61,7 +67,7 @@ const VideoThumbnail = styled.div`
61
67
  &::after {
62
68
  content: '';
63
69
  border: ${({ borderWidth }) => borderWidth}px solid;
64
- border-color: ${({ isPlaying, borderColor }) => (isPlaying ? borderColor : 'transparent')};
70
+ border-color: ${({ borderColor }) => borderColor};
65
71
  border-radius: ${({ borderRadius }) => borderRadius}px;
66
72
  position: absolute;
67
73
  top: 0;
@@ -94,27 +100,30 @@ const VideoPickerThumbnail = ({
94
100
  width = '100%'
95
101
  }) => {
96
102
  const viewport = useViewport()
97
- const { titleColor, subTitleColor, ...themeTokens } = useThemeTokens('VideoPickerThumbnail')
103
+ const getTokens = useThemeTokensCallback('VideoPickerThumbnail', {}, {})
98
104
 
99
- const rnStyles = createReactNativeStyles(themeTokens)
100
105
  const { timestamp } = getTimestamp(video.videoLength, video.copy)
101
106
  const isPlaying = selectedVideoId === video.videoId
102
107
 
103
- const renderThumbnailImage = () => (
104
- <VideoThumbnail {...themeTokens} isPlaying={isPlaying} layout={layout}>
105
- <VideoSplash
106
- simpleMode
107
- poster={video.posterSrc || `https://img.youtube.com/vi/${video.videoId}/maxresdefault.jpg`}
108
- videoLength={video.videoLength}
109
- copy={video.copy}
110
- />
111
- </VideoThumbnail>
112
- )
108
+ const renderThumbnailImage = (themeTokens) => {
109
+ return (
110
+ <VideoThumbnail {...themeTokens} isPlaying={isPlaying} layout={layout}>
111
+ <VideoSplash
112
+ simpleMode
113
+ poster={
114
+ video.posterSrc || `https://img.youtube.com/vi/${video.videoId}/maxresdefault.jpg`
115
+ }
116
+ videoLength={video.videoLength}
117
+ copy={video.copy}
118
+ />
119
+ </VideoThumbnail>
120
+ )
121
+ }
113
122
 
114
- const renderThumbnailInfo = () => (
123
+ const renderThumbnailInfo = ({ titleColor, subTitleColor }) => (
115
124
  <StackView space={2} tokens={{ flexShrink: 1 }}>
116
125
  <ThumbnailTitleContainer viewport={viewport}>
117
- <Typography variant={{ bold: true }} tokens={{ color: isPlaying ? titleColor : 'none' }}>
126
+ <Typography variant={{ bold: true }} tokens={{ color: titleColor }}>
118
127
  {video.title}
119
128
  </Typography>
120
129
  </ThumbnailTitleContainer>
@@ -148,21 +157,33 @@ const VideoPickerThumbnail = ({
148
157
  onKeyPress={onKeyPress}
149
158
  accessibilityRole="radio"
150
159
  accessibilityState={{ checked: isPlaying }}
151
- style={[
152
- rnStyles.container,
153
- layout === 'horizontal' && rnStyles.horizontal,
154
- isFramed && rnStyles.framed,
155
- isFramed && index > 0 && rnStyles.framedLine,
156
- { width }
157
- ]}
160
+ style={({ hovered: hover, focused: focus, pressed }) => {
161
+ const themeTokens = getTokens({ hover, focus, pressed, selected: isPlaying })
162
+
163
+ const rnStyles = createReactNativeStyles(themeTokens)
164
+ return [
165
+ rnStyles.container,
166
+ layout === 'horizontal' && rnStyles.horizontal,
167
+ isFramed && rnStyles.framed,
168
+ isFramed && index > 0 && rnStyles.framedLine,
169
+ { width },
170
+ { outline: 'none' }
171
+ ]
172
+ }}
158
173
  >
159
- <StackView
160
- space={layout === 'vertical' ? 2 : 3}
161
- direction={layout === 'vertical' ? 'column' : 'row'}
162
- >
163
- {renderThumbnailImage()}
164
- {renderThumbnailInfo()}
165
- </StackView>
174
+ {({ hovered: hover, focused: focus, pressed }) => {
175
+ const themeTokens = getTokens({ hover, focus, pressed, selected: isPlaying })
176
+
177
+ return (
178
+ <StackView
179
+ space={layout === 'vertical' ? 2 : 3}
180
+ direction={layout === 'vertical' ? 'column' : 'row'}
181
+ >
182
+ <ImageContainer {...themeTokens}>{renderThumbnailImage(themeTokens)}</ImageContainer>
183
+ {renderThumbnailInfo(themeTokens)}
184
+ </StackView>
185
+ )
186
+ }}
166
187
  </Pressable>
167
188
  )
168
189
  }
@@ -26,7 +26,7 @@ const VideoSlider = ({ children }) => {
26
26
  setContainerWidth(width)
27
27
  }
28
28
 
29
- const itemsGap = 24 // '4' on spacing scale
29
+ const itemsGap = 32 // '5' on spacing scale
30
30
  const itemsCount = viewport === 'lg' || viewport === 'xl' ? 4 : 3
31
31
  const itemGapPortioned = ((itemsCount - 1) * itemsGap) / itemsCount
32
32
  const itemWidth =
@@ -40,7 +40,7 @@ const VideoSlider = ({ children }) => {
40
40
  )
41
41
 
42
42
  const content = (
43
- <StackView space={4} direction="row" accessibilityRole="radiogroup" tokens={{ flexGrow: 1 }}>
43
+ <StackView space={5} direction="row" accessibilityRole="radiogroup" tokens={{ flexGrow: 1 }}>
44
44
  {React.Children.map(children, (child, index) =>
45
45
  cloneElement(child, {
46
46
  index,
@@ -0,0 +1,25 @@
1
+ import type { ComponentType } from 'react'
2
+
3
+ declare interface ThemeMetadata {
4
+ themeTokensVersion: string
5
+ name: string
6
+ }
7
+
8
+ declare interface DefaultTheme {
9
+ metadata: ThemeMetadata
10
+ }
11
+
12
+ declare interface ThemeOptions {
13
+ forceAbsoluteFontSizing?: boolean
14
+ forceZIndex?: boolean
15
+ }
16
+
17
+ export interface BaseProviderProps {
18
+ themeOptions?: ThemeOptions
19
+ defaultTheme: DefaultTheme
20
+ children: React.ReactNode
21
+ }
22
+
23
+ declare const BaseProvider: ComponentType<BaseProviderProps>
24
+
25
+ export default BaseProvider
package/types/index.d.ts CHANGED
@@ -112,7 +112,7 @@ declare const Pagination: ComponentType<Props> & {
112
112
 
113
113
  export { default as QuantitySelector } from './QuantitySelector'
114
114
  export type { QuantitySelectorProps } from './QuantitySelector'
115
-
115
+ export { default as BaseProvider } from './BaseProvider'
116
116
  declare const QuickLinks: ComponentType<Props> & {
117
117
  Item: ComponentType<Props>
118
118
  }