@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,92 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { getTokensPropType, selectSystemProps, useThemeTokens, useViewport, variantProp } from '@telus-uds/components-base';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { htmlAttrs } from '../utils';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
8
|
+
const CardContentContainer = /*#__PURE__*/styled.div.withConfig({
|
|
9
|
+
displayName: "CardContent__CardContentContainer",
|
|
10
|
+
componentId: "components-web__sc-1k2501q-0"
|
|
11
|
+
})(_ref => {
|
|
12
|
+
let {
|
|
13
|
+
backgroundColor,
|
|
14
|
+
borderRadius,
|
|
15
|
+
paddingBottom,
|
|
16
|
+
paddingLeft,
|
|
17
|
+
paddingRight,
|
|
18
|
+
paddingTop,
|
|
19
|
+
withFooter,
|
|
20
|
+
contentAlignItem: alignItem,
|
|
21
|
+
contentFlexGrow: flexGrow,
|
|
22
|
+
contentFlexShrink: flexShrink,
|
|
23
|
+
contentJustifyContent: justifyContent
|
|
24
|
+
} = _ref;
|
|
25
|
+
return {
|
|
26
|
+
backgroundColor,
|
|
27
|
+
// We need to make sure to have sharp corners on the bottom
|
|
28
|
+
// if the card has a footer
|
|
29
|
+
borderBottomLeftRadius: withFooter ? 0 : borderRadius,
|
|
30
|
+
borderBottomRightRadius: withFooter ? 0 : borderRadius,
|
|
31
|
+
borderTopLeftRadius: borderRadius,
|
|
32
|
+
borderTopRightRadius: borderRadius,
|
|
33
|
+
paddingBottom,
|
|
34
|
+
paddingLeft,
|
|
35
|
+
paddingRight,
|
|
36
|
+
paddingTop,
|
|
37
|
+
display: 'flex',
|
|
38
|
+
flexDirection: 'column',
|
|
39
|
+
alignItem,
|
|
40
|
+
flexGrow,
|
|
41
|
+
flexShrink,
|
|
42
|
+
justifyContent
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* Card content, applying the card tokens as per the theme used.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
const CardContent = _ref2 => {
|
|
50
|
+
let {
|
|
51
|
+
children,
|
|
52
|
+
flexContent,
|
|
53
|
+
tokens,
|
|
54
|
+
variant,
|
|
55
|
+
withFooter = false,
|
|
56
|
+
...rest
|
|
57
|
+
} = _ref2;
|
|
58
|
+
const viewport = useViewport();
|
|
59
|
+
const themeTokens = useThemeTokens('Card', tokens, variant, {
|
|
60
|
+
viewport
|
|
61
|
+
});
|
|
62
|
+
return /*#__PURE__*/_jsx(CardContentContainer, { ...themeTokens,
|
|
63
|
+
flexContent: flexContent,
|
|
64
|
+
withFooter: withFooter,
|
|
65
|
+
...selectProps(rest),
|
|
66
|
+
children: children
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
CardContent.propTypes = { ...selectedSystemPropTypes,
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Card section content.
|
|
74
|
+
*/
|
|
75
|
+
children: PropTypes.node,
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Card tokens.
|
|
79
|
+
*/
|
|
80
|
+
tokens: getTokensPropType('Card'),
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Card variant.
|
|
84
|
+
*/
|
|
85
|
+
variant: variantProp.propType,
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Whether the card has a footer.
|
|
89
|
+
*/
|
|
90
|
+
withFooter: PropTypes.bool
|
|
91
|
+
};
|
|
92
|
+
export default CardContent;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { getTokensPropType, paddingProp, selectSystemProps, useThemeTokens, useViewport, variantProp } from '@telus-uds/components-base';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { htmlAttrs } from '../utils';
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
8
|
+
const CardFooterContainer = /*#__PURE__*/styled.div.withConfig({
|
|
9
|
+
displayName: "CardFooter__CardFooterContainer",
|
|
10
|
+
componentId: "components-web__sc-pm6vns-0"
|
|
11
|
+
})(_ref => {
|
|
12
|
+
let {
|
|
13
|
+
backgroundColor,
|
|
14
|
+
borderRadius,
|
|
15
|
+
paddingBottom,
|
|
16
|
+
paddingLeft,
|
|
17
|
+
paddingRight,
|
|
18
|
+
paddingTop
|
|
19
|
+
} = _ref;
|
|
20
|
+
return {
|
|
21
|
+
backgroundColor,
|
|
22
|
+
borderBottomLeftRadius: borderRadius,
|
|
23
|
+
borderBottomRightRadius: borderRadius,
|
|
24
|
+
// @todo circle back to the following non-standard value to
|
|
25
|
+
// see if it can be integrated into the palette
|
|
26
|
+
boxShadow: 'inset 0px 1px 3px rgba(0, 0, 0, 0.05)',
|
|
27
|
+
paddingBottom,
|
|
28
|
+
paddingLeft,
|
|
29
|
+
paddingRight,
|
|
30
|
+
paddingTop
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Card footer, applying the tokens as per the theme used.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
const CardFooter = _ref2 => {
|
|
38
|
+
let {
|
|
39
|
+
children,
|
|
40
|
+
padding,
|
|
41
|
+
tokens,
|
|
42
|
+
variant,
|
|
43
|
+
...rest
|
|
44
|
+
} = _ref2;
|
|
45
|
+
const viewport = useViewport();
|
|
46
|
+
const themeTokens = useThemeTokens('Card', tokens, { ...variant,
|
|
47
|
+
background: 'alternative'
|
|
48
|
+
}, {
|
|
49
|
+
viewport
|
|
50
|
+
});
|
|
51
|
+
return /*#__PURE__*/_jsx(CardFooterContainer, { ...themeTokens,
|
|
52
|
+
...padding,
|
|
53
|
+
...selectProps(rest),
|
|
54
|
+
children: children
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
CardFooter.propTypes = { ...selectedSystemPropTypes,
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Card footer content.
|
|
62
|
+
*/
|
|
63
|
+
children: PropTypes.node,
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Card footer padding.
|
|
67
|
+
*/
|
|
68
|
+
padding: paddingProp.propType,
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Card tokens.
|
|
72
|
+
*/
|
|
73
|
+
tokens: getTokensPropType('Card'),
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Card variant.
|
|
77
|
+
*/
|
|
78
|
+
variant: variantProp.propType
|
|
79
|
+
};
|
|
80
|
+
export default CardFooter;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
2
|
+
import React, { forwardRef } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { Spacer, StackView, Typography, selectSystemProps, useViewport, useThemeTokens, applyTextStyles } from '@telus-uds/components-base';
|
|
5
|
+
import { viewports } from '@telus-uds/system-constants';
|
|
6
|
+
import styled from 'styled-components'; // Reading these from the RN palette since they will be used to generate
|
|
7
|
+
// the `Typography` tokens
|
|
8
|
+
|
|
9
|
+
import { htmlAttrs, transformGradient } from '../utils';
|
|
10
|
+
import Segment from './Segment';
|
|
11
|
+
import useCountdown from './useCountdown';
|
|
12
|
+
import { countdownVariantPropType, dictionaryContentShape } from './types';
|
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
16
|
+
const Container = /*#__PURE__*/styled.div.withConfig({
|
|
17
|
+
displayName: "Countdown__Container",
|
|
18
|
+
componentId: "components-web__sc-18tqcb2-0"
|
|
19
|
+
})(_ref => {
|
|
20
|
+
let {
|
|
21
|
+
variant: {
|
|
22
|
+
feature,
|
|
23
|
+
inverse,
|
|
24
|
+
large
|
|
25
|
+
},
|
|
26
|
+
themeTokens,
|
|
27
|
+
gradient
|
|
28
|
+
} = _ref;
|
|
29
|
+
return { ...(large || feature && {
|
|
30
|
+
display: 'flex',
|
|
31
|
+
flex: 0
|
|
32
|
+
}),
|
|
33
|
+
...(feature && {
|
|
34
|
+
borderRadius: themeTokens.containerBorderRadius,
|
|
35
|
+
justifyContent: 'center',
|
|
36
|
+
paddingBottom: `${themeTokens.containerPaddingBottomTop}px`,
|
|
37
|
+
paddingLeft: `${themeTokens.containerPaddingLeftRight}px`,
|
|
38
|
+
paddingRight: `${themeTokens.containerPaddingLeftRight}px`,
|
|
39
|
+
paddingTop: `${themeTokens.containerPaddingBottomTop}px`,
|
|
40
|
+
width: 'fit-content'
|
|
41
|
+
}),
|
|
42
|
+
...(feature && !inverse && {
|
|
43
|
+
background: `linear-gradient(#fff 0 0) padding-box, ${gradient} border-box`,
|
|
44
|
+
border: `${themeTokens.containerInverseBorder}px solid transparent`
|
|
45
|
+
}),
|
|
46
|
+
...(feature && inverse && {
|
|
47
|
+
border: `${themeTokens.containerInverseBorder}px solid ${themeTokens.inverseBorderColor}`
|
|
48
|
+
})
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const getLabelTokens = themeTokens => ({
|
|
53
|
+
color: themeTokens.labelBorderColor,
|
|
54
|
+
fontWeight: themeTokens.textTimerFontWeight,
|
|
55
|
+
fontSize: `${themeTokens.labelFontSize}`,
|
|
56
|
+
lineHeight: `${themeTokens.labelLineHeight}`
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const getMainTextTokens = themeTokens => ({
|
|
60
|
+
color: themeTokens.labelBorderColor,
|
|
61
|
+
fontWeight: themeTokens.textTimerFontWeight,
|
|
62
|
+
fontSize: themeTokens.textFontSize,
|
|
63
|
+
lineHeight: themeTokens.textLineHeight
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const Countdown = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
67
|
+
let {
|
|
68
|
+
copy = 'en',
|
|
69
|
+
targetTime,
|
|
70
|
+
tokens,
|
|
71
|
+
variant = {},
|
|
72
|
+
...rest
|
|
73
|
+
} = _ref2;
|
|
74
|
+
const [days, hours, minutes, seconds] = useCountdown(targetTime);
|
|
75
|
+
const viewport = useViewport();
|
|
76
|
+
const {
|
|
77
|
+
feature,
|
|
78
|
+
large,
|
|
79
|
+
label,
|
|
80
|
+
noDivider
|
|
81
|
+
} = variant;
|
|
82
|
+
|
|
83
|
+
if (noDivider && !label) {
|
|
84
|
+
throw new Error('`noDivider` variant can only be used with `label` enabled!');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const themeTokens = useThemeTokens('Countdown', tokens, variant, {
|
|
88
|
+
viewport
|
|
89
|
+
});
|
|
90
|
+
const segmentFontSize = themeTokens.textFontSize;
|
|
91
|
+
const semanticGradient = themeTokens.containerGradient && transformGradient(themeTokens.containerGradient);
|
|
92
|
+
const mainTextTokens = getMainTextTokens(themeTokens);
|
|
93
|
+
const divider = noDivider === true ?
|
|
94
|
+
/*#__PURE__*/
|
|
95
|
+
// StackView-based subcontainer adds a 1-step space on the each side of the divider
|
|
96
|
+
_jsx(Spacer, {
|
|
97
|
+
direction: "row",
|
|
98
|
+
space: (feature || large) && viewport !== viewports.xs ? 7 : 2
|
|
99
|
+
}) : /*#__PURE__*/_jsx(Typography, {
|
|
100
|
+
tokens: mainTextTokens,
|
|
101
|
+
children: ":"
|
|
102
|
+
});
|
|
103
|
+
const labelTokens = getLabelTokens(themeTokens);
|
|
104
|
+
const commonProps = {
|
|
105
|
+
copy,
|
|
106
|
+
labelTokens,
|
|
107
|
+
numberTokens: mainTextTokens,
|
|
108
|
+
segmentFontSize,
|
|
109
|
+
variant
|
|
110
|
+
};
|
|
111
|
+
return (
|
|
112
|
+
/*#__PURE__*/
|
|
113
|
+
// Making it focusable for accessibility purposes
|
|
114
|
+
_jsx(Container, {
|
|
115
|
+
ref: ref,
|
|
116
|
+
variant: variant,
|
|
117
|
+
...selectProps(rest),
|
|
118
|
+
tabIndex: 0,
|
|
119
|
+
themeTokens: themeTokens,
|
|
120
|
+
gradient: semanticGradient,
|
|
121
|
+
children: /*#__PURE__*/_jsxs(StackView, {
|
|
122
|
+
direction: "row",
|
|
123
|
+
space: 1,
|
|
124
|
+
children: [/*#__PURE__*/_jsx(Segment, {
|
|
125
|
+
labelKey: "day",
|
|
126
|
+
number: days,
|
|
127
|
+
segmentWidth: String(days).length,
|
|
128
|
+
...commonProps
|
|
129
|
+
}), divider, /*#__PURE__*/_jsx(Segment, {
|
|
130
|
+
labelKey: "hour",
|
|
131
|
+
number: hours,
|
|
132
|
+
...commonProps,
|
|
133
|
+
...applyTextStyles(themeTokens)
|
|
134
|
+
}), divider, /*#__PURE__*/_jsx(Segment, {
|
|
135
|
+
labelKey: "minute",
|
|
136
|
+
number: minutes,
|
|
137
|
+
...commonProps,
|
|
138
|
+
...applyTextStyles(themeTokens)
|
|
139
|
+
}), divider, /*#__PURE__*/_jsx(Segment, {
|
|
140
|
+
labelKey: "second",
|
|
141
|
+
number: seconds,
|
|
142
|
+
...commonProps,
|
|
143
|
+
...applyTextStyles(themeTokens)
|
|
144
|
+
})]
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
Countdown.displayName = 'Countdown';
|
|
150
|
+
Countdown.propTypes = { ...selectedSystemPropTypes,
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Copy language identifier (`'en'` or `'fr'`) or a dictionary instance (an object with
|
|
154
|
+
* the following keys: days, day, hours, hour, minutes, minute, seconds, second)
|
|
155
|
+
*/
|
|
156
|
+
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), dictionaryContentShape]),
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* An instance of JavaScript `Date` object or a string parseable via `Date.parse()`
|
|
160
|
+
* representing a point in the future to count down to.
|
|
161
|
+
*/
|
|
162
|
+
targetTime: PropTypes.instanceOf(Date),
|
|
163
|
+
variant: countdownVariantPropType
|
|
164
|
+
};
|
|
165
|
+
export default Countdown;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { StackView, Typography, useCopy } from '@telus-uds/components-base';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import dictionary from './dictionary';
|
|
6
|
+
import { countdownVariantPropType, dictionaryContentShape } from './types';
|
|
7
|
+
import { SEGMENT_WIDTH_TO_FONT_SIZE_RATIO } from './constants'; // Pads with zeros on the left if it's a single digit number
|
|
8
|
+
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
|
|
12
|
+
const pad = function (number) {
|
|
13
|
+
let segmentWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
|
|
14
|
+
return String(number).padStart(segmentWidth, '0');
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const Container = /*#__PURE__*/styled.div.withConfig({
|
|
18
|
+
displayName: "Segment__Container",
|
|
19
|
+
componentId: "components-web__sc-yrh35y-0"
|
|
20
|
+
})(_ref => {
|
|
21
|
+
let {
|
|
22
|
+
segmentFontSize,
|
|
23
|
+
segmentWidth = 2,
|
|
24
|
+
variant: {
|
|
25
|
+
feature
|
|
26
|
+
}
|
|
27
|
+
} = _ref;
|
|
28
|
+
return {
|
|
29
|
+
justifyContent: 'space-evenly',
|
|
30
|
+
display: 'inline-flex',
|
|
31
|
+
...(feature && {
|
|
32
|
+
width: `${segmentFontSize * SEGMENT_WIDTH_TO_FONT_SIZE_RATIO * segmentWidth}px`,
|
|
33
|
+
display: 'flex'
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
}); // A segment of the countdown string: we need to make sure it
|
|
37
|
+
// keeps its width constant to prevent the whole component from
|
|
38
|
+
// being automatically resized while using variable size fonts
|
|
39
|
+
|
|
40
|
+
const Segment = _ref2 => {
|
|
41
|
+
let {
|
|
42
|
+
copy = 'en',
|
|
43
|
+
segmentFontSize,
|
|
44
|
+
labelKey,
|
|
45
|
+
labelTokens,
|
|
46
|
+
number,
|
|
47
|
+
numberTokens,
|
|
48
|
+
segmentWidth = 2,
|
|
49
|
+
variant = {}
|
|
50
|
+
} = _ref2;
|
|
51
|
+
const getCopy = useCopy({
|
|
52
|
+
dictionary,
|
|
53
|
+
copy
|
|
54
|
+
});
|
|
55
|
+
const {
|
|
56
|
+
label,
|
|
57
|
+
large,
|
|
58
|
+
feature
|
|
59
|
+
} = variant;
|
|
60
|
+
return /*#__PURE__*/_jsx(Container, {
|
|
61
|
+
segmentFontSize: segmentFontSize,
|
|
62
|
+
segmentWidth: segmentWidth,
|
|
63
|
+
variant: variant,
|
|
64
|
+
children: /*#__PURE__*/_jsxs(StackView, {
|
|
65
|
+
direction: large || feature ? 'column' : 'row',
|
|
66
|
+
space: large || feature ? 0 : 1,
|
|
67
|
+
tokens: {
|
|
68
|
+
alignItems: 'center'
|
|
69
|
+
},
|
|
70
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
71
|
+
tokens: numberTokens,
|
|
72
|
+
children: pad(number, segmentWidth)
|
|
73
|
+
}), label && /*#__PURE__*/_jsx(Typography, {
|
|
74
|
+
tokens: labelTokens,
|
|
75
|
+
children: getCopy(number === 1 ? labelKey : `${labelKey}s`)
|
|
76
|
+
})]
|
|
77
|
+
})
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Segment.propTypes = {
|
|
82
|
+
/**
|
|
83
|
+
* Copy language identifier or a dictionary instance.
|
|
84
|
+
*/
|
|
85
|
+
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), dictionaryContentShape]),
|
|
86
|
+
segmentFontSize: PropTypes.number,
|
|
87
|
+
labelKey: PropTypes.oneOf(['day', 'hour', 'minute', 'second']),
|
|
88
|
+
labelTokens: PropTypes.object,
|
|
89
|
+
number: PropTypes.number,
|
|
90
|
+
numberTokens: PropTypes.object,
|
|
91
|
+
segmentWidth: PropTypes.number,
|
|
92
|
+
variant: countdownVariantPropType
|
|
93
|
+
};
|
|
94
|
+
export default Segment;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
en: {
|
|
3
|
+
days: 'Days',
|
|
4
|
+
day: 'Day',
|
|
5
|
+
hours: 'Hours',
|
|
6
|
+
hour: 'Hour',
|
|
7
|
+
minutes: 'Minutes',
|
|
8
|
+
minute: 'Minute',
|
|
9
|
+
seconds: 'Seconds',
|
|
10
|
+
second: 'Second'
|
|
11
|
+
},
|
|
12
|
+
fr: {
|
|
13
|
+
days: 'Jours',
|
|
14
|
+
day: 'Jour',
|
|
15
|
+
hours: 'Heures',
|
|
16
|
+
hour: 'Heure',
|
|
17
|
+
minutes: 'Minutes',
|
|
18
|
+
minute: 'Minute',
|
|
19
|
+
seconds: 'Secondes',
|
|
20
|
+
second: 'Seconde'
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
export const countdownVariantPropType = PropTypes.shape({
|
|
3
|
+
feature: PropTypes.bool,
|
|
4
|
+
inverse: PropTypes.bool,
|
|
5
|
+
label: PropTypes.bool,
|
|
6
|
+
large: PropTypes.bool,
|
|
7
|
+
noDivider: PropTypes.bool
|
|
8
|
+
}); // If a language dictionary entry is provided, it must contain every key
|
|
9
|
+
|
|
10
|
+
export const dictionaryContentShape = PropTypes.shape({
|
|
11
|
+
days: PropTypes.string.isRequired,
|
|
12
|
+
day: PropTypes.string.isRequired,
|
|
13
|
+
hours: PropTypes.string.isRequired,
|
|
14
|
+
hour: PropTypes.string.isRequired,
|
|
15
|
+
minutes: PropTypes.string.isRequired,
|
|
16
|
+
minute: PropTypes.string.isRequired,
|
|
17
|
+
seconds: PropTypes.string.isRequired,
|
|
18
|
+
second: PropTypes.string.isRequired
|
|
19
|
+
});
|
|
20
|
+
export default {
|
|
21
|
+
countdownVariantPropType,
|
|
22
|
+
dictionaryContentShape
|
|
23
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
const getTimeCounts = countdown => {
|
|
4
|
+
if (countdown <= 0) {
|
|
5
|
+
return [0, 0, 0, 0];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const days = Math.floor(countdown / (1000 * 60 * 60 * 24));
|
|
9
|
+
const hours = Math.floor(countdown % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
|
|
10
|
+
const minutes = Math.floor(countdown % (1000 * 60 * 60) / (1000 * 60));
|
|
11
|
+
const seconds = Math.floor(countdown % (1000 * 60) / 1000);
|
|
12
|
+
return [days, hours, minutes, seconds];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const useCountdown = targetTime => {
|
|
16
|
+
const countdownTime = new Date(targetTime).getTime();
|
|
17
|
+
|
|
18
|
+
if (!countdownTime) {
|
|
19
|
+
throw new Error('Invalid target time is provided!');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const [countdown, setCountdown] = useState(countdownTime - new Date().getTime());
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const interval = setInterval(() => {
|
|
25
|
+
setCountdown(countdownTime - new Date().getTime());
|
|
26
|
+
}, 1000);
|
|
27
|
+
return () => clearInterval(interval);
|
|
28
|
+
}, [countdownTime]);
|
|
29
|
+
return getTimeCounts(countdown);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default useCountdown;
|
|
@@ -27,9 +27,15 @@ const StyledSubHeading = /*#__PURE__*/styled.div.withConfig({
|
|
|
27
27
|
} = _ref2;
|
|
28
28
|
return marginTop;
|
|
29
29
|
});
|
|
30
|
+
const StyledTextButtonContainer = /*#__PURE__*/styled.div.withConfig({
|
|
31
|
+
displayName: "ModalContent__StyledTextButtonContainer",
|
|
32
|
+
componentId: "components-web__sc-k40cwb-3"
|
|
33
|
+
})({
|
|
34
|
+
display: 'flex'
|
|
35
|
+
});
|
|
30
36
|
const StyledFooter = /*#__PURE__*/styled.footer.withConfig({
|
|
31
37
|
displayName: "ModalContent__StyledFooter",
|
|
32
|
-
componentId: "components-web__sc-k40cwb-
|
|
38
|
+
componentId: "components-web__sc-k40cwb-4"
|
|
33
39
|
})(_ref3 => {
|
|
34
40
|
let {
|
|
35
41
|
hasBorder,
|
|
@@ -143,15 +149,15 @@ const ModalContent = _ref4 => {
|
|
|
143
149
|
},
|
|
144
150
|
onPress: onConfirm,
|
|
145
151
|
children: confirmButtonText
|
|
146
|
-
}), /*#__PURE__*/_jsx(
|
|
147
|
-
children:
|
|
152
|
+
}), hasCancelButton ? /*#__PURE__*/_jsx(StyledTextButtonContainer, {
|
|
153
|
+
children: /*#__PURE__*/_jsx(CancelButton, {
|
|
148
154
|
tokens: {
|
|
149
155
|
color: cancelButtonColor
|
|
150
156
|
},
|
|
151
157
|
onPress: onCancel,
|
|
152
158
|
children: cancelButtonText
|
|
153
159
|
})
|
|
154
|
-
})]
|
|
160
|
+
}) : null]
|
|
155
161
|
})]
|
|
156
162
|
});
|
|
157
163
|
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { selectSystemProps } from '@telus-uds/components-base';
|
|
4
|
+
import ResponsiveImage from '../ResponsiveImage';
|
|
5
|
+
import { hasWebpSupport, getOptimizedUrl, getFallbackUrl } from './utils';
|
|
6
|
+
import { htmlAttrs } from '../utils';
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
9
|
+
|
|
10
|
+
const OptimizeImage = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
contentfulAssetUrl,
|
|
13
|
+
alt,
|
|
14
|
+
quality = 80,
|
|
15
|
+
xs = 320,
|
|
16
|
+
sm = 576,
|
|
17
|
+
md = 768,
|
|
18
|
+
lg = 992,
|
|
19
|
+
xl = 1200,
|
|
20
|
+
sizeByHeight = false,
|
|
21
|
+
disableRetina = false,
|
|
22
|
+
...rest
|
|
23
|
+
} = _ref;
|
|
24
|
+
const [imgUrls, setImgUrls] = useState(); // `useHeight` is a deprecated TDS prop, replaced by `sizeByHeight`
|
|
25
|
+
|
|
26
|
+
const dimension = sizeByHeight || rest.useHeight ? 'h' : 'w';
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
// Currently not all browsers support webP
|
|
29
|
+
hasWebpSupport().then(supportsWebp => {
|
|
30
|
+
setImgUrls({
|
|
31
|
+
xsSrc: getOptimizedUrl(contentfulAssetUrl, dimension, xs, quality, disableRetina, supportsWebp),
|
|
32
|
+
smSrc: getOptimizedUrl(contentfulAssetUrl, dimension, sm, quality, disableRetina, supportsWebp),
|
|
33
|
+
mdSrc: getOptimizedUrl(contentfulAssetUrl, dimension, md, quality, disableRetina, supportsWebp),
|
|
34
|
+
lgSrc: getOptimizedUrl(contentfulAssetUrl, dimension, lg, quality, disableRetina, supportsWebp),
|
|
35
|
+
xlSrc: getOptimizedUrl(contentfulAssetUrl, dimension, xl, quality, disableRetina, supportsWebp),
|
|
36
|
+
fallbackSrc: getFallbackUrl(contentfulAssetUrl, xl, quality)
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs]);
|
|
40
|
+
if (!imgUrls) return null;
|
|
41
|
+
return /*#__PURE__*/_jsx(ResponsiveImage, { ...imgUrls,
|
|
42
|
+
alt: alt,
|
|
43
|
+
...selectProps(rest)
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
OptimizeImage.propTypes = { ...selectedSystemPropTypes,
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The source to load the image. Only contentful image urls are supported. See https://www.contentful.com/developers/docs/references/images-api/ for details.
|
|
51
|
+
*/
|
|
52
|
+
contentfulAssetUrl: PropTypes.string.isRequired,
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Alternative text to display if image cannot be loaded or a screen reader is used.
|
|
56
|
+
*/
|
|
57
|
+
alt: PropTypes.string.isRequired,
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Customize quality as a percentage between 1 and 100.
|
|
61
|
+
*/
|
|
62
|
+
quality: PropTypes.number,
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Customize width for xs screen size in px, this may affect the quality of the image.
|
|
66
|
+
*/
|
|
67
|
+
xs: PropTypes.number,
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Customize width for sm screen size in px, this may affect the quality of the image.
|
|
71
|
+
*/
|
|
72
|
+
sm: PropTypes.number,
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Customize width for md screen size in px, this may affect the quality of the image.
|
|
76
|
+
*/
|
|
77
|
+
md: PropTypes.number,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Customize width for lg screen size in px, this may affect the quality of the image.
|
|
81
|
+
*/
|
|
82
|
+
lg: PropTypes.number,
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Customize width for xl screen size in px, this may affect the quality of the image.
|
|
86
|
+
*/
|
|
87
|
+
xl: PropTypes.number,
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Switches size dimension to height, default is false
|
|
91
|
+
*/
|
|
92
|
+
sizeByHeight: PropTypes.bool,
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Turns off retina display functionality
|
|
96
|
+
*/
|
|
97
|
+
disableRetina: PropTypes.bool,
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Loading strategy.
|
|
101
|
+
* @default 'eager'
|
|
102
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading
|
|
103
|
+
*/
|
|
104
|
+
loading: PropTypes.oneOf(['eager', 'lazy'])
|
|
105
|
+
};
|
|
106
|
+
export default OptimizeImage;
|