@telus-uds/components-web 1.8.0 → 1.9.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 +27 -2
- package/lib/Autocomplete/Autocomplete.js +393 -0
- package/lib/Autocomplete/Loading.js +51 -0
- package/lib/Autocomplete/Suggestions.js +81 -0
- package/lib/Autocomplete/constants.js +19 -0
- package/lib/Autocomplete/dictionary.js +19 -0
- package/lib/Autocomplete/index.js +13 -0
- package/lib/Callout/Callout.js +3 -0
- package/lib/Card/Card.js +180 -0
- package/lib/Card/CardContent.js +110 -0
- package/lib/Card/CardFooter.js +98 -0
- package/lib/Card/index.js +13 -0
- package/lib/Countdown/Countdown.js +189 -0
- package/lib/Countdown/Segment.js +111 -0
- package/lib/Countdown/constants.js +14 -0
- package/lib/Countdown/dictionary.js +29 -0
- package/lib/Countdown/index.js +13 -0
- package/lib/Countdown/types.js +39 -0
- package/lib/Countdown/useCountdown.js +40 -0
- package/lib/Modal/ModalContent.js +11 -4
- package/lib/OptimizeImage/OptimizeImage.js +127 -0
- package/lib/OptimizeImage/index.js +13 -0
- package/lib/OptimizeImage/utils/getFallbackUrl.js +18 -0
- package/lib/OptimizeImage/utils/getOptimizedUrl.js +32 -0
- package/lib/OptimizeImage/utils/hasWebpSupport.js +38 -0
- package/lib/OptimizeImage/utils/index.js +31 -0
- package/lib/OptimizeImage/utils/isSvgUrl.js +10 -0
- package/lib/QuantitySelector/QuantitySelector.js +253 -0
- package/lib/QuantitySelector/dictionary.js +33 -0
- package/lib/QuantitySelector/index.js +13 -0
- package/lib/QuantitySelector/styles.js +40 -0
- package/lib/StoryCard/StoryCard.js +244 -0
- package/lib/StoryCard/index.js +13 -0
- package/lib/TermsAndConditions/ExpandCollapse.js +141 -0
- package/lib/TermsAndConditions/TermsAndConditions.js +221 -0
- package/lib/TermsAndConditions/dictionary.js +19 -0
- package/lib/TermsAndConditions/index.js +15 -0
- package/lib/Testimonial/Testimonial.js +226 -0
- package/lib/Testimonial/index.js +13 -0
- package/lib/Video/ControlBar/ControlBar.js +315 -0
- package/lib/Video/ControlBar/Controls/VideoButton/VideoButton.js +91 -0
- package/lib/Video/ControlBar/Controls/VideoMenu/VideoMenu.js +186 -0
- package/lib/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.js +221 -0
- package/lib/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.js +213 -0
- package/lib/Video/MiddleControlButton/MiddleControlButton.js +89 -0
- package/lib/Video/Video.js +1072 -0
- package/lib/Video/index.js +13 -0
- package/lib/Video/videoText.js +62 -0
- package/lib/WebVideo/WebVideo.js +170 -0
- package/lib/WebVideo/index.js +13 -0
- package/lib/baseExports.js +0 -6
- package/lib/index.js +91 -1
- package/lib/shared/VideoSplash/SplashButton/SplashButton.js +102 -0
- package/lib/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.js +234 -0
- package/lib/shared/VideoSplash/VideoSplash.js +86 -0
- package/lib/shared/VideoSplash/helpers.js +38 -0
- package/lib/utils/index.js +8 -0
- package/lib-module/Autocomplete/Autocomplete.js +369 -0
- package/lib-module/Autocomplete/Loading.js +38 -0
- package/lib-module/Autocomplete/Suggestions.js +64 -0
- package/lib-module/Autocomplete/constants.js +5 -0
- package/lib-module/Autocomplete/dictionary.js +12 -0
- package/lib-module/Autocomplete/index.js +2 -0
- package/lib-module/Callout/Callout.js +3 -0
- package/lib-module/Card/Card.js +158 -0
- package/lib-module/Card/CardContent.js +92 -0
- package/lib-module/Card/CardFooter.js +80 -0
- package/lib-module/Card/index.js +2 -0
- package/lib-module/Countdown/Countdown.js +165 -0
- package/lib-module/Countdown/Segment.js +94 -0
- package/lib-module/Countdown/constants.js +4 -0
- package/lib-module/Countdown/dictionary.js +22 -0
- package/lib-module/Countdown/index.js +2 -0
- package/lib-module/Countdown/types.js +23 -0
- package/lib-module/Countdown/useCountdown.js +32 -0
- package/lib-module/Modal/ModalContent.js +10 -4
- package/lib-module/OptimizeImage/OptimizeImage.js +106 -0
- package/lib-module/OptimizeImage/index.js +2 -0
- package/lib-module/OptimizeImage/utils/getFallbackUrl.js +8 -0
- package/lib-module/OptimizeImage/utils/getOptimizedUrl.js +22 -0
- package/lib-module/OptimizeImage/utils/hasWebpSupport.js +32 -0
- package/lib-module/OptimizeImage/utils/index.js +4 -0
- package/lib-module/OptimizeImage/utils/isSvgUrl.js +3 -0
- package/lib-module/QuantitySelector/QuantitySelector.js +232 -0
- package/lib-module/QuantitySelector/dictionary.js +26 -0
- package/lib-module/QuantitySelector/index.js +2 -0
- package/lib-module/QuantitySelector/styles.js +21 -0
- package/lib-module/StoryCard/StoryCard.js +220 -0
- package/lib-module/StoryCard/index.js +2 -0
- package/lib-module/TermsAndConditions/ExpandCollapse.js +120 -0
- package/lib-module/TermsAndConditions/TermsAndConditions.js +193 -0
- package/lib-module/TermsAndConditions/dictionary.js +12 -0
- package/lib-module/TermsAndConditions/index.js +1 -0
- package/lib-module/Testimonial/Testimonial.js +204 -0
- package/lib-module/Testimonial/index.js +2 -0
- package/lib-module/Video/ControlBar/ControlBar.js +292 -0
- package/lib-module/Video/ControlBar/Controls/VideoButton/VideoButton.js +74 -0
- package/lib-module/Video/ControlBar/Controls/VideoMenu/VideoMenu.js +167 -0
- package/lib-module/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.js +201 -0
- package/lib-module/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.js +193 -0
- package/lib-module/Video/MiddleControlButton/MiddleControlButton.js +72 -0
- package/lib-module/Video/Video.js +1042 -0
- package/lib-module/Video/index.js +2 -0
- package/lib-module/Video/videoText.js +55 -0
- package/lib-module/WebVideo/WebVideo.js +144 -0
- package/lib-module/WebVideo/index.js +2 -0
- package/lib-module/baseExports.js +1 -1
- package/lib-module/index.js +10 -0
- package/lib-module/shared/VideoSplash/SplashButton/SplashButton.js +85 -0
- package/lib-module/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.js +216 -0
- package/lib-module/shared/VideoSplash/VideoSplash.js +65 -0
- package/lib-module/shared/VideoSplash/helpers.js +23 -0
- package/lib-module/utils/index.js +2 -1
- package/package.json +7 -5
- package/src/Autocomplete/Autocomplete.jsx +354 -0
- package/src/Autocomplete/Loading.jsx +18 -0
- package/src/Autocomplete/Suggestions.jsx +52 -0
- package/src/Autocomplete/constants.js +6 -0
- package/src/Autocomplete/dictionary.js +12 -0
- package/src/Autocomplete/index.js +3 -0
- package/src/Callout/Callout.jsx +1 -1
- package/src/Card/Card.jsx +170 -0
- package/src/Card/CardContent.jsx +88 -0
- package/src/Card/CardFooter.jsx +70 -0
- package/src/Card/index.js +3 -0
- package/src/Countdown/Countdown.jsx +144 -0
- package/src/Countdown/Segment.jsx +69 -0
- package/src/Countdown/constants.js +4 -0
- package/src/Countdown/dictionary.js +22 -0
- package/src/Countdown/index.js +3 -0
- package/src/Countdown/types.js +23 -0
- package/src/Countdown/useCountdown.js +34 -0
- package/src/Modal/ModalContent.jsx +8 -4
- package/src/OptimizeImage/OptimizeImage.jsx +131 -0
- package/src/OptimizeImage/index.js +3 -0
- package/src/OptimizeImage/utils/getFallbackUrl.js +9 -0
- package/src/OptimizeImage/utils/getOptimizedUrl.js +30 -0
- package/src/OptimizeImage/utils/hasWebpSupport.js +33 -0
- package/src/OptimizeImage/utils/index.js +5 -0
- package/src/OptimizeImage/utils/isSvgUrl.js +3 -0
- package/src/QuantitySelector/QuantitySelector.jsx +245 -0
- package/src/QuantitySelector/dictionary.js +27 -0
- package/src/QuantitySelector/index.js +3 -0
- package/src/QuantitySelector/styles.js +83 -0
- package/src/StoryCard/StoryCard.jsx +198 -0
- package/src/StoryCard/index.js +3 -0
- package/src/TermsAndConditions/ExpandCollapse.jsx +106 -0
- package/src/TermsAndConditions/TermsAndConditions.jsx +161 -0
- package/src/TermsAndConditions/dictionary.js +12 -0
- package/src/TermsAndConditions/index.js +1 -0
- package/src/Testimonial/Testimonial.jsx +169 -0
- package/src/Testimonial/index.js +3 -0
- package/src/Video/ControlBar/ControlBar.jsx +261 -0
- package/src/Video/ControlBar/Controls/VideoButton/VideoButton.jsx +61 -0
- package/src/Video/ControlBar/Controls/VideoMenu/VideoMenu.jsx +159 -0
- package/src/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.jsx +185 -0
- package/src/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.jsx +184 -0
- package/src/Video/MiddleControlButton/MiddleControlButton.jsx +64 -0
- package/src/Video/Video.jsx +988 -0
- package/src/Video/index.js +3 -0
- package/src/Video/videoText.js +58 -0
- package/src/WebVideo/WebVideo.jsx +131 -0
- package/src/WebVideo/index.js +3 -0
- package/src/baseExports.js +0 -1
- package/src/index.js +10 -0
- package/src/shared/VideoSplash/SplashButton/SplashButton.jsx +64 -0
- package/src/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.jsx +128 -0
- package/src/shared/VideoSplash/VideoSplash.jsx +50 -0
- package/src/shared/VideoSplash/helpers.js +27 -0
- package/src/utils/index.js +10 -1
- package/types/Autocomplete.d.ts +32 -0
- package/types/Card.d.ts +45 -0
- package/types/ControlBar.d.ts +59 -0
- package/types/MiddleControlButton.d.ts +15 -0
- package/types/Video.d.ts +39 -0
- package/types/VideoButton.d.ts +14 -0
- package/types/VideoMenu.d.ts +16 -0
- package/types/VideoProgressBar.d.ts +17 -0
- package/types/VolumeSlider.d.ts +20 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import {
|
|
4
|
+
ExpandCollapse as ExpandCollapseBase,
|
|
5
|
+
Icon,
|
|
6
|
+
useThemeTokensCallback
|
|
7
|
+
} from '@telus-uds/components-base'
|
|
8
|
+
import styled from 'styled-components'
|
|
9
|
+
|
|
10
|
+
const ExpandCollapseControl = styled.div({
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
cursor: 'pointer',
|
|
13
|
+
display: 'flex',
|
|
14
|
+
flex: 1,
|
|
15
|
+
justifyContent: 'flex-start'
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const ExpandCollapseIconContainer = styled.div(({ tokens }) => ({
|
|
19
|
+
alignItems: tokens.expandIconContainerAlignItems,
|
|
20
|
+
border: `${tokens.expandIconContainerBorder}px solid ${tokens.expandIconContainerBorderColor}`,
|
|
21
|
+
borderRadius: '50%',
|
|
22
|
+
display: 'flex',
|
|
23
|
+
height: tokens.expandIconContainerHeight,
|
|
24
|
+
justifyContent: tokens.expandIconContainerJustifyContent,
|
|
25
|
+
margin: `${tokens.expandIconContainerMarginX}px ${tokens.expandIconContainerMarginY}px`,
|
|
26
|
+
width: tokens.expandIconContainerWidth
|
|
27
|
+
}))
|
|
28
|
+
|
|
29
|
+
const ExpandCollapseTitle = styled.h4(({ tokens }) => ({
|
|
30
|
+
color: tokens.expandTitleColor,
|
|
31
|
+
fontFamily: `${tokens.listFontName}${tokens.listFontWeight}normal`,
|
|
32
|
+
fontSize: tokens.expandTitleFontSize,
|
|
33
|
+
lineHeight: tokens.expandTitleLineHeight,
|
|
34
|
+
margin: `${tokens.expandTitleMarginX}px ${tokens.expandTitleMarginY}px`
|
|
35
|
+
}))
|
|
36
|
+
|
|
37
|
+
const ExpandCollapse = forwardRef(
|
|
38
|
+
({ children, collapseTitle, expandTitle = collapseTitle }, ref) => {
|
|
39
|
+
const getTokens = useThemeTokensCallback('TermsAndConditions', {}, {})
|
|
40
|
+
const {
|
|
41
|
+
expandBaseBorderWidth,
|
|
42
|
+
expandContentPaddingBottom,
|
|
43
|
+
expandContentPaddingLeft,
|
|
44
|
+
expandContentPaddingRight,
|
|
45
|
+
expandContentPaddingTop
|
|
46
|
+
} = getTokens()
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<ExpandCollapseBase
|
|
50
|
+
tokens={{
|
|
51
|
+
borderWidth: expandBaseBorderWidth
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
{(expandProps) => (
|
|
55
|
+
<ExpandCollapseBase.Panel
|
|
56
|
+
{...expandProps}
|
|
57
|
+
panelId="ExpandCollapsePanel"
|
|
58
|
+
controlTokens={{ icon: null }}
|
|
59
|
+
// TODO refactor
|
|
60
|
+
// eslint-disable-next-line react/no-unstable-nested-components
|
|
61
|
+
control={(pressableState) => {
|
|
62
|
+
const { expanded } = pressableState || {}
|
|
63
|
+
const { icon } = getTokens({ expanded })
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<ExpandCollapseControl
|
|
67
|
+
onClick={(event) => expandProps.onToggle('ExpandCollapsePanel', event)}
|
|
68
|
+
ref={ref}
|
|
69
|
+
>
|
|
70
|
+
<ExpandCollapseIconContainer tokens={getTokens()}>
|
|
71
|
+
<Icon icon={icon} variant={{ size: 'small' }} />
|
|
72
|
+
</ExpandCollapseIconContainer>
|
|
73
|
+
<ExpandCollapseTitle tokens={getTokens()}>
|
|
74
|
+
{expanded ? expandTitle : collapseTitle}
|
|
75
|
+
</ExpandCollapseTitle>
|
|
76
|
+
</ExpandCollapseControl>
|
|
77
|
+
)
|
|
78
|
+
}}
|
|
79
|
+
tokens={{
|
|
80
|
+
contentPaddingBottom: expandContentPaddingBottom,
|
|
81
|
+
contentPaddingLeft: expandContentPaddingLeft,
|
|
82
|
+
contentPaddingRight: expandContentPaddingRight,
|
|
83
|
+
contentPaddingTop: expandContentPaddingTop
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
{children}
|
|
87
|
+
</ExpandCollapseBase.Panel>
|
|
88
|
+
)}
|
|
89
|
+
</ExpandCollapseBase>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
ExpandCollapse.displayName = 'ExpandCollapse'
|
|
95
|
+
|
|
96
|
+
ExpandCollapse.propTypes = {
|
|
97
|
+
children: PropTypes.node.isRequired,
|
|
98
|
+
collapseTitle: PropTypes.string.isRequired,
|
|
99
|
+
expandTitle: PropTypes.string
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ExpandCollapse.defaultProps = {
|
|
103
|
+
expandTitle: undefined
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export default ExpandCollapse
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import {
|
|
5
|
+
Box,
|
|
6
|
+
Divider,
|
|
7
|
+
selectSystemProps,
|
|
8
|
+
Typography,
|
|
9
|
+
useCopy,
|
|
10
|
+
useThemeTokens
|
|
11
|
+
} from '@telus-uds/components-base'
|
|
12
|
+
import ExpandCollapse from './ExpandCollapse'
|
|
13
|
+
import OrderedListBase from '../OrderedList/OrderedListBase'
|
|
14
|
+
import { htmlAttrs, media, renderStructuredContent } from '../utils'
|
|
15
|
+
import dictionary from './dictionary'
|
|
16
|
+
|
|
17
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
18
|
+
|
|
19
|
+
const ContentContainer = styled.div(({ tokens }) => ({
|
|
20
|
+
paddingBottom: tokens.contentPaddingBottom,
|
|
21
|
+
paddingLeft: tokens.contentPaddingLeft,
|
|
22
|
+
...media().from('md').css({
|
|
23
|
+
paddingBottom: tokens.mdContentPaddingBottom,
|
|
24
|
+
paddingLeft: tokens.mdContentPaddingLeft
|
|
25
|
+
})
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
const Ordered = styled(OrderedListBase)(({ tokens }) => ({
|
|
29
|
+
listStylePosition: 'outside',
|
|
30
|
+
padding: tokens.orderedPadding
|
|
31
|
+
}))
|
|
32
|
+
|
|
33
|
+
const Unordered = styled.ul(({ tokens }) => ({
|
|
34
|
+
listStyleType: 'none',
|
|
35
|
+
margin: 0,
|
|
36
|
+
padding: tokens.unorderedPadding
|
|
37
|
+
}))
|
|
38
|
+
|
|
39
|
+
const ListItem = styled(OrderedListBase.Item)(({ tokens }) => ({
|
|
40
|
+
display: 'list-item',
|
|
41
|
+
'&::marker': {
|
|
42
|
+
fontFamily: `${tokens.listFontName}${tokens.listFontWeight}normal`,
|
|
43
|
+
fontSize: tokens.listFontSize,
|
|
44
|
+
lineHeight: tokens.listLineHeight,
|
|
45
|
+
textAlign: 'end !important'
|
|
46
|
+
},
|
|
47
|
+
color: tokens.listColor,
|
|
48
|
+
fontFamily: `${tokens.listFontName}${tokens.listFontWeight}normal`,
|
|
49
|
+
fontSize: tokens.listFontSize,
|
|
50
|
+
lineHeight: tokens.listLineHeight,
|
|
51
|
+
marginBottom: tokens.listMarginBottom,
|
|
52
|
+
marginLeft: tokens.listMarginLeft,
|
|
53
|
+
wordBreak: 'break-word'
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
const NonIndexedContentTitle = styled.div(({ tokens }) => ({
|
|
57
|
+
color: tokens.titleColor,
|
|
58
|
+
fontSize: tokens.titleFontSize,
|
|
59
|
+
lineHeight: tokens.titleLineHeight,
|
|
60
|
+
paddingLeft: tokens.titlePaddingLeft
|
|
61
|
+
}))
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Use `TermsAndConditions` to display important legal content.
|
|
65
|
+
*
|
|
66
|
+
* ## Usage Criteria
|
|
67
|
+
*
|
|
68
|
+
* - Display before the page footer, except for call-to-action callback cards
|
|
69
|
+
* - Responsive display based on breakpoints
|
|
70
|
+
* - Use `copy` to set language, ‘en’ for English or ‘fr’ for French
|
|
71
|
+
*/
|
|
72
|
+
const TermsAndConditions = forwardRef(
|
|
73
|
+
({ copy = 'en', indexedContent, nonIndexedContent, tokens, variant = {}, ...rest }, ref) => {
|
|
74
|
+
const getCopy = useCopy({ dictionary, copy })
|
|
75
|
+
const hasIndexedContent = indexedContent.length > 0
|
|
76
|
+
const hasNonIndexedContent = nonIndexedContent.length > 0
|
|
77
|
+
|
|
78
|
+
const themeTokens = useThemeTokens('TermsAndConditions', tokens, variant)
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div {...selectProps(rest)}>
|
|
82
|
+
<Divider />
|
|
83
|
+
<ExpandCollapse
|
|
84
|
+
collapseTitle={getCopy('headingView')}
|
|
85
|
+
expandTitle={getCopy('headingHide')}
|
|
86
|
+
ref={ref}
|
|
87
|
+
>
|
|
88
|
+
<ContentContainer tokens={themeTokens}>
|
|
89
|
+
{hasIndexedContent && (
|
|
90
|
+
<Ordered tokens={themeTokens}>
|
|
91
|
+
{indexedContent.map((contentItem, idx) => (
|
|
92
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
93
|
+
<ListItem tokens={themeTokens} key={idx}>
|
|
94
|
+
{renderStructuredContent(contentItem)}
|
|
95
|
+
</ListItem>
|
|
96
|
+
))}
|
|
97
|
+
</Ordered>
|
|
98
|
+
)}
|
|
99
|
+
{hasNonIndexedContent && (
|
|
100
|
+
<Box between={3}>
|
|
101
|
+
<NonIndexedContentTitle tokens={themeTokens}>
|
|
102
|
+
<Typography block heading variant={{ size: 'h4' }}>
|
|
103
|
+
{getCopy('nonIndexedTitle')}
|
|
104
|
+
</Typography>
|
|
105
|
+
</NonIndexedContentTitle>
|
|
106
|
+
<Unordered tokens={themeTokens}>
|
|
107
|
+
{nonIndexedContent.map((contentItem, idx) => (
|
|
108
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
109
|
+
<ListItem tokens={themeTokens} key={idx}>
|
|
110
|
+
{renderStructuredContent(contentItem)}
|
|
111
|
+
</ListItem>
|
|
112
|
+
))}
|
|
113
|
+
</Unordered>
|
|
114
|
+
</Box>
|
|
115
|
+
)}
|
|
116
|
+
</ContentContainer>
|
|
117
|
+
</ExpandCollapse>
|
|
118
|
+
<Divider />
|
|
119
|
+
</div>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
TermsAndConditions.displayName = 'TermsAndConditions'
|
|
125
|
+
|
|
126
|
+
TermsAndConditions.propTypes = {
|
|
127
|
+
...selectedSystemPropTypes,
|
|
128
|
+
/**
|
|
129
|
+
* Use the `copy` prop to either select provided English or French copy by passing 'en' or 'fr' respectively.
|
|
130
|
+
*
|
|
131
|
+
* To provide your own, pass a JSON object with the keys `headingView`, `headingHide`, and `nonIndexedTitle`.
|
|
132
|
+
*/
|
|
133
|
+
copy: PropTypes.oneOfType([
|
|
134
|
+
PropTypes.oneOf(['en', 'fr']),
|
|
135
|
+
PropTypes.shape({
|
|
136
|
+
headingView: PropTypes.string,
|
|
137
|
+
headingHide: PropTypes.string,
|
|
138
|
+
nonIndexedTitle: PropTypes.string
|
|
139
|
+
})
|
|
140
|
+
]),
|
|
141
|
+
/**
|
|
142
|
+
* An array of nodes, strings, or a combination to be displayed in an ordered list.
|
|
143
|
+
*
|
|
144
|
+
* Each item in the array must have a corresponding superscript in the page.
|
|
145
|
+
*/
|
|
146
|
+
indexedContent: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.node, PropTypes.string])),
|
|
147
|
+
/**
|
|
148
|
+
* An array of nodes, strings, or a combination to be displayed in an unordered list.
|
|
149
|
+
*
|
|
150
|
+
* nonIndexedContent do not have a corresponding superscript and instead apply to the page as a whole.
|
|
151
|
+
*/
|
|
152
|
+
nonIndexedContent: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.node, PropTypes.string]))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
TermsAndConditions.defaultProps = {
|
|
156
|
+
copy: 'en',
|
|
157
|
+
indexedContent: [],
|
|
158
|
+
nonIndexedContent: []
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export default TermsAndConditions
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
en: {
|
|
3
|
+
headingHide: 'Hide terms and conditions',
|
|
4
|
+
headingView: 'View terms and conditions',
|
|
5
|
+
nonIndexedTitle: 'The following applies to all terms and conditions above'
|
|
6
|
+
},
|
|
7
|
+
fr: {
|
|
8
|
+
headingHide: 'Masquer les modalités et conditions',
|
|
9
|
+
headingView: 'Voir les modalités et conditions',
|
|
10
|
+
nonIndexedTitle: 'Ce qui suit s’applique aux modalités et conditions ci-dessus'
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './TermsAndConditions'
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import { Icon, selectSystemProps, Typography, useThemeTokens } from '@telus-uds/components-base'
|
|
5
|
+
import Image from '../Image'
|
|
6
|
+
import { htmlAttrs } from '../utils'
|
|
7
|
+
|
|
8
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
9
|
+
|
|
10
|
+
const TestimonialContainer = styled.figure(({ testimonialContainerGap }) => ({
|
|
11
|
+
display: 'flex',
|
|
12
|
+
flexDirection: 'column',
|
|
13
|
+
gap: testimonialContainerGap,
|
|
14
|
+
margin: 0
|
|
15
|
+
}))
|
|
16
|
+
|
|
17
|
+
const QuoteContainer = styled.div(({ quoteContainerGap }) => ({
|
|
18
|
+
display: 'flex',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
gap: quoteContainerGap
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
const Divider = styled.div(({ dividerBorder, dividerBackgroundColor }) => ({
|
|
24
|
+
height: dividerBorder,
|
|
25
|
+
background: dividerBackgroundColor,
|
|
26
|
+
width: '100%'
|
|
27
|
+
}))
|
|
28
|
+
|
|
29
|
+
const BlockQuote = styled.blockquote({
|
|
30
|
+
margin: 0
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const AuthorInfoContainer = styled.div({
|
|
34
|
+
display: 'flex',
|
|
35
|
+
flexDirection: 'column'
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const Figcaption = styled.figcaption(({ figcaptionGap }) => ({
|
|
39
|
+
display: 'flex',
|
|
40
|
+
alignItems: 'center',
|
|
41
|
+
gap: figcaptionGap
|
|
42
|
+
}))
|
|
43
|
+
|
|
44
|
+
const Testimonial = ({
|
|
45
|
+
showDivider,
|
|
46
|
+
testimonial,
|
|
47
|
+
title,
|
|
48
|
+
imageSrc,
|
|
49
|
+
image = imageSrc,
|
|
50
|
+
additionalInfo,
|
|
51
|
+
testimonialStyle = 'heading',
|
|
52
|
+
tokens,
|
|
53
|
+
variant = {},
|
|
54
|
+
...rest
|
|
55
|
+
}) => {
|
|
56
|
+
const {
|
|
57
|
+
testimonialContainerGap,
|
|
58
|
+
quoteContainerGap,
|
|
59
|
+
dividerBorder,
|
|
60
|
+
dividerBackgroundColor,
|
|
61
|
+
figcaptionGap,
|
|
62
|
+
textColor,
|
|
63
|
+
icon,
|
|
64
|
+
iconColor,
|
|
65
|
+
imageSize
|
|
66
|
+
} = useThemeTokens('Testimonial', tokens, variant)
|
|
67
|
+
return (
|
|
68
|
+
<TestimonialContainer testimonialContainerGap={testimonialContainerGap} {...selectProps(rest)}>
|
|
69
|
+
<QuoteContainer quoteContainerGap={quoteContainerGap}>
|
|
70
|
+
<Icon tokens={{ color: iconColor }} variant={{ size: 'micro' }} icon={icon} />
|
|
71
|
+
{showDivider && (
|
|
72
|
+
<Divider
|
|
73
|
+
dividerBackgroundColor={dividerBackgroundColor}
|
|
74
|
+
dividerBorder={dividerBorder}
|
|
75
|
+
role="separator"
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
</QuoteContainer>
|
|
79
|
+
<BlockQuote>
|
|
80
|
+
<Typography
|
|
81
|
+
variant={{ size: testimonialStyle === 'large' ? 'large' : 'h3' }}
|
|
82
|
+
tokens={{
|
|
83
|
+
color: textColor,
|
|
84
|
+
fontWeight: '400'
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
{`\u201C${testimonial}\u201D`}
|
|
88
|
+
</Typography>
|
|
89
|
+
</BlockQuote>
|
|
90
|
+
{(image || title || additionalInfo) && (
|
|
91
|
+
<Figcaption figcaptionGap={figcaptionGap}>
|
|
92
|
+
{image &&
|
|
93
|
+
(typeof image === 'string' ? (
|
|
94
|
+
<Image
|
|
95
|
+
rounded="circle"
|
|
96
|
+
src={image}
|
|
97
|
+
alt={title}
|
|
98
|
+
width={imageSize}
|
|
99
|
+
height={imageSize}
|
|
100
|
+
/>
|
|
101
|
+
) : (
|
|
102
|
+
image
|
|
103
|
+
))}
|
|
104
|
+
{(title || additionalInfo) && (
|
|
105
|
+
<AuthorInfoContainer>
|
|
106
|
+
{title && (
|
|
107
|
+
<Typography
|
|
108
|
+
variant={{ size: 'small', colour: 'secondary' }}
|
|
109
|
+
tokens={{ fontWeight: '500' }}
|
|
110
|
+
>
|
|
111
|
+
{title}
|
|
112
|
+
</Typography>
|
|
113
|
+
)}
|
|
114
|
+
{additionalInfo && (
|
|
115
|
+
<Typography
|
|
116
|
+
variant={{ size: 'micro', colour: 'secondary' }}
|
|
117
|
+
tokens={{ fontWeight: '400' }}
|
|
118
|
+
>
|
|
119
|
+
{additionalInfo}
|
|
120
|
+
</Typography>
|
|
121
|
+
)}
|
|
122
|
+
</AuthorInfoContainer>
|
|
123
|
+
)}
|
|
124
|
+
</Figcaption>
|
|
125
|
+
)}
|
|
126
|
+
{showDivider && (
|
|
127
|
+
<Divider
|
|
128
|
+
dividerBackgroundColor={dividerBackgroundColor}
|
|
129
|
+
dividerBorder={dividerBorder}
|
|
130
|
+
role="separator"
|
|
131
|
+
/>
|
|
132
|
+
)}
|
|
133
|
+
</TestimonialContainer>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
Testimonial.propTypes = {
|
|
138
|
+
...selectedSystemPropTypes,
|
|
139
|
+
/**
|
|
140
|
+
* Testimonial content
|
|
141
|
+
*/
|
|
142
|
+
testimonial: PropTypes.string.isRequired,
|
|
143
|
+
/**
|
|
144
|
+
* Testimonial author or source
|
|
145
|
+
*/
|
|
146
|
+
title: PropTypes.string,
|
|
147
|
+
/**
|
|
148
|
+
* Additional information on the author or source
|
|
149
|
+
*/
|
|
150
|
+
additionalInfo: PropTypes.string,
|
|
151
|
+
/**
|
|
152
|
+
* Testimonial style
|
|
153
|
+
*/
|
|
154
|
+
testimonialStyle: PropTypes.oneOf(['large', 'heading']),
|
|
155
|
+
/**
|
|
156
|
+
* Whether to show or not dividers at the top and the bottom of the testimonial
|
|
157
|
+
showDivider: PropTypes.bool,
|
|
158
|
+
/**
|
|
159
|
+
* The src attribute for the Image component or custom JSX content to render instead
|
|
160
|
+
*/
|
|
161
|
+
image: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
162
|
+
/**
|
|
163
|
+
* The src attribute for the `Image` component to be displayed on the testimonial
|
|
164
|
+
* @deprecated please use the `image` prop instead
|
|
165
|
+
*/
|
|
166
|
+
imageSrc: PropTypes.string
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export default Testimonial
|