@telus-uds/components-web 2.12.0 → 2.14.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 +40 -2
- package/component-docs.json +105 -43
- package/lib/Autocomplete/Loading.js +5 -10
- package/lib/Autocomplete/dictionary.js +2 -2
- package/lib/Badge/Badge.js +10 -1
- package/lib/DatePicker/DatePicker.js +13 -0
- package/lib/NavigationBar/NavigationSubMenu.js +4 -8
- package/lib/QuantitySelector/QuantitySelector.js +67 -66
- package/lib/QuantitySelector/SideButton.js +93 -0
- package/lib/QuantitySelector/styles.js +4 -20
- package/lib/Spinner/Spinner.js +10 -1
- package/lib/Spinner/SpinnerContent.js +8 -0
- package/lib/Table/Cell.js +62 -91
- package/lib/Table/Header.js +4 -1
- package/lib/Table/SubHeading.js +4 -1
- package/lib/Table/Table.js +2 -1
- package/lib/TermsAndConditions/ExpandCollapse.js +31 -13
- package/lib/TermsAndConditions/TermsAndConditions.js +42 -10
- package/lib/Testimonial/Testimonial.js +48 -12
- package/lib/VideoPicker/VideoPickerPlayer.js +4 -2
- package/lib/VideoPicker/VideoPickerThumbnail.js +103 -60
- package/lib/VideoPicker/VideoSlider.js +2 -2
- package/lib-module/Autocomplete/Loading.js +6 -12
- package/lib-module/Autocomplete/dictionary.js +2 -2
- package/lib-module/Badge/Badge.js +10 -1
- package/lib-module/DatePicker/DatePicker.js +13 -1
- package/lib-module/NavigationBar/NavigationSubMenu.js +5 -9
- package/lib-module/QuantitySelector/QuantitySelector.js +68 -67
- package/lib-module/QuantitySelector/SideButton.js +80 -0
- package/lib-module/QuantitySelector/styles.js +3 -15
- package/lib-module/Spinner/Spinner.js +10 -1
- package/lib-module/Spinner/SpinnerContent.js +8 -0
- package/lib-module/Table/Cell.js +65 -90
- package/lib-module/Table/Header.js +4 -1
- package/lib-module/Table/SubHeading.js +4 -1
- package/lib-module/Table/Table.js +2 -1
- package/lib-module/TermsAndConditions/ExpandCollapse.js +33 -15
- package/lib-module/TermsAndConditions/TermsAndConditions.js +42 -11
- package/lib-module/Testimonial/Testimonial.js +49 -13
- package/lib-module/VideoPicker/VideoPickerPlayer.js +4 -2
- package/lib-module/VideoPicker/VideoPickerThumbnail.js +103 -61
- package/lib-module/VideoPicker/VideoSlider.js +2 -2
- package/package.json +4 -4
- package/src/Autocomplete/Loading.jsx +2 -5
- package/src/Autocomplete/dictionary.js +2 -2
- package/src/Badge/Badge.jsx +14 -2
- package/src/DatePicker/DatePicker.jsx +14 -1
- package/src/NavigationBar/NavigationSubMenu.jsx +3 -4
- package/src/QuantitySelector/QuantitySelector.jsx +60 -76
- package/src/QuantitySelector/SideButton.jsx +74 -0
- package/src/QuantitySelector/styles.js +4 -70
- package/src/Spinner/Spinner.jsx +9 -1
- package/src/Spinner/SpinnerContent.jsx +13 -1
- package/src/Table/Cell.jsx +58 -78
- package/src/Table/Header.jsx +6 -1
- package/src/Table/SubHeading.jsx +4 -1
- package/src/Table/Table.jsx +10 -2
- package/src/TermsAndConditions/ExpandCollapse.jsx +36 -14
- package/src/TermsAndConditions/TermsAndConditions.jsx +48 -10
- package/src/Testimonial/Testimonial.jsx +73 -11
- package/src/VideoPicker/VideoPickerPlayer.jsx +2 -2
- package/src/VideoPicker/VideoPickerThumbnail.jsx +51 -30
- package/src/VideoPicker/VideoSlider.jsx +2 -2
- package/types/BaseProvider.d.ts +25 -0
- package/types/index.d.ts +1 -1
|
@@ -4,7 +4,7 @@ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { viewports } from '@telus-uds/system-constants';
|
|
6
6
|
import styled from 'styled-components';
|
|
7
|
-
import { StackView, Typography, useViewport, horizontalScrollUtils,
|
|
7
|
+
import { StackView, Typography, useViewport, horizontalScrollUtils, useThemeTokensCallback } from '@telus-uds/components-base';
|
|
8
8
|
import { getTimestamp } from '../shared/VideoSplash/helpers';
|
|
9
9
|
import { VideoPropType, RefPropType } from './videoPropType';
|
|
10
10
|
import VideoSplash from '../shared/VideoSplash/VideoSplash';
|
|
@@ -42,37 +42,45 @@ const createReactNativeStyles = _ref => {
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
const
|
|
46
|
-
displayName: "
|
|
45
|
+
const ImageContainer = /*#__PURE__*/styled.div.withConfig({
|
|
46
|
+
displayName: "VideoPickerThumbnail__ImageContainer",
|
|
47
47
|
componentId: "components-web__sc-1glxurq-0"
|
|
48
|
-
})(["
|
|
48
|
+
})(["padding:", ";border:", ";border-radius:", "px;"], props => `${props.outerBorderGap}px`, props => `${props.outerBorderWidth}px solid ${props.outerBorderColor}`, _ref2 => {
|
|
49
49
|
let {
|
|
50
|
-
|
|
50
|
+
outerBorderRadius
|
|
51
51
|
} = _ref2;
|
|
52
|
-
return
|
|
53
|
-
}
|
|
52
|
+
return outerBorderRadius;
|
|
53
|
+
});
|
|
54
|
+
const VideoThumbnail = /*#__PURE__*/styled.div.withConfig({
|
|
55
|
+
displayName: "VideoPickerThumbnail__VideoThumbnail",
|
|
56
|
+
componentId: "components-web__sc-1glxurq-1"
|
|
57
|
+
})(["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', _ref3 => {
|
|
54
58
|
let {
|
|
55
|
-
|
|
56
|
-
borderColor
|
|
59
|
+
borderWidth
|
|
57
60
|
} = _ref3;
|
|
58
|
-
return
|
|
61
|
+
return borderWidth;
|
|
59
62
|
}, _ref4 => {
|
|
60
63
|
let {
|
|
61
|
-
|
|
64
|
+
borderColor
|
|
62
65
|
} = _ref4;
|
|
63
|
-
return
|
|
66
|
+
return borderColor;
|
|
64
67
|
}, _ref5 => {
|
|
65
68
|
let {
|
|
66
69
|
borderRadius
|
|
67
70
|
} = _ref5;
|
|
68
71
|
return borderRadius;
|
|
72
|
+
}, _ref6 => {
|
|
73
|
+
let {
|
|
74
|
+
borderRadius
|
|
75
|
+
} = _ref6;
|
|
76
|
+
return borderRadius;
|
|
69
77
|
});
|
|
70
78
|
const ThumbnailTitleContainer = /*#__PURE__*/styled.div.withConfig({
|
|
71
79
|
displayName: "VideoPickerThumbnail__ThumbnailTitleContainer",
|
|
72
|
-
componentId: "components-web__sc-1glxurq-
|
|
80
|
+
componentId: "components-web__sc-1glxurq-2"
|
|
73
81
|
})(["display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;"]);
|
|
74
82
|
|
|
75
|
-
const VideoPickerThumbnail =
|
|
83
|
+
const VideoPickerThumbnail = _ref7 => {
|
|
76
84
|
let {
|
|
77
85
|
videoPlayerRef,
|
|
78
86
|
selectedVideoId,
|
|
@@ -83,56 +91,59 @@ const VideoPickerThumbnail = _ref6 => {
|
|
|
83
91
|
itemPositions,
|
|
84
92
|
index,
|
|
85
93
|
width = '100%'
|
|
86
|
-
} =
|
|
94
|
+
} = _ref7;
|
|
87
95
|
const viewport = useViewport();
|
|
88
|
-
const {
|
|
89
|
-
titleColor,
|
|
90
|
-
subTitleColor,
|
|
91
|
-
...themeTokens
|
|
92
|
-
} = useThemeTokens('VideoPickerThumbnail');
|
|
93
|
-
const rnStyles = createReactNativeStyles(themeTokens);
|
|
96
|
+
const getTokens = useThemeTokensCallback('VideoPickerThumbnail', {}, {});
|
|
94
97
|
const {
|
|
95
98
|
timestamp
|
|
96
99
|
} = getTimestamp(video.videoLength, video.copy);
|
|
97
100
|
const isPlaying = selectedVideoId === video.videoId;
|
|
98
101
|
|
|
99
|
-
const renderThumbnailImage =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
const renderThumbnailImage = themeTokens => {
|
|
103
|
+
return /*#__PURE__*/_jsx(VideoThumbnail, { ...themeTokens,
|
|
104
|
+
isPlaying: isPlaying,
|
|
105
|
+
layout: layout,
|
|
106
|
+
children: /*#__PURE__*/_jsx(VideoSplash, {
|
|
107
|
+
simpleMode: true,
|
|
108
|
+
poster: video.posterSrc || `https://img.youtube.com/vi/${video.videoId}/maxresdefault.jpg`,
|
|
109
|
+
videoLength: video.videoLength,
|
|
110
|
+
copy: video.copy
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
};
|
|
109
114
|
|
|
110
|
-
const renderThumbnailInfo =
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
const renderThumbnailInfo = _ref8 => {
|
|
116
|
+
let {
|
|
117
|
+
titleColor,
|
|
118
|
+
subTitleColor
|
|
119
|
+
} = _ref8;
|
|
120
|
+
return /*#__PURE__*/_jsxs(StackView, {
|
|
121
|
+
space: 2,
|
|
122
|
+
tokens: {
|
|
123
|
+
flexShrink: 1
|
|
124
|
+
},
|
|
125
|
+
children: [/*#__PURE__*/_jsx(ThumbnailTitleContainer, {
|
|
126
|
+
viewport: viewport,
|
|
127
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
128
|
+
variant: {
|
|
129
|
+
bold: true
|
|
130
|
+
},
|
|
131
|
+
tokens: {
|
|
132
|
+
color: titleColor
|
|
133
|
+
},
|
|
134
|
+
children: video.title
|
|
135
|
+
})
|
|
136
|
+
}), viewport !== viewports.xs && /*#__PURE__*/_jsx(Typography, {
|
|
118
137
|
variant: {
|
|
119
|
-
|
|
138
|
+
size: 'micro'
|
|
120
139
|
},
|
|
121
140
|
tokens: {
|
|
122
|
-
color:
|
|
141
|
+
color: subTitleColor
|
|
123
142
|
},
|
|
124
|
-
children:
|
|
125
|
-
})
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
size: 'micro'
|
|
129
|
-
},
|
|
130
|
-
tokens: {
|
|
131
|
-
color: subTitleColor
|
|
132
|
-
},
|
|
133
|
-
children: timestamp
|
|
134
|
-
})]
|
|
135
|
-
});
|
|
143
|
+
children: timestamp
|
|
144
|
+
})]
|
|
145
|
+
});
|
|
146
|
+
};
|
|
136
147
|
|
|
137
148
|
const handleLayout = itemPositions !== undefined ? getItemPositionLayoutHandler(itemPositions.positions, index) : undefined;
|
|
138
149
|
|
|
@@ -155,14 +166,45 @@ const VideoPickerThumbnail = _ref6 => {
|
|
|
155
166
|
accessibilityState: {
|
|
156
167
|
checked: isPlaying
|
|
157
168
|
},
|
|
158
|
-
style:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
style: _ref9 => {
|
|
170
|
+
let {
|
|
171
|
+
hovered: hover,
|
|
172
|
+
focused: focus,
|
|
173
|
+
pressed
|
|
174
|
+
} = _ref9;
|
|
175
|
+
const themeTokens = getTokens({
|
|
176
|
+
hover,
|
|
177
|
+
focus,
|
|
178
|
+
pressed,
|
|
179
|
+
selected: isPlaying
|
|
180
|
+
});
|
|
181
|
+
const rnStyles = createReactNativeStyles(themeTokens);
|
|
182
|
+
return [rnStyles.container, layout === 'horizontal' && rnStyles.horizontal, isFramed && rnStyles.framed, isFramed && index > 0 && rnStyles.framedLine, {
|
|
183
|
+
width
|
|
184
|
+
}, {
|
|
185
|
+
outline: 'none'
|
|
186
|
+
}];
|
|
187
|
+
},
|
|
188
|
+
children: _ref10 => {
|
|
189
|
+
let {
|
|
190
|
+
hovered: hover,
|
|
191
|
+
focused: focus,
|
|
192
|
+
pressed
|
|
193
|
+
} = _ref10;
|
|
194
|
+
const themeTokens = getTokens({
|
|
195
|
+
hover,
|
|
196
|
+
focus,
|
|
197
|
+
pressed,
|
|
198
|
+
selected: isPlaying
|
|
199
|
+
});
|
|
200
|
+
return /*#__PURE__*/_jsxs(StackView, {
|
|
201
|
+
space: layout === 'vertical' ? 2 : 3,
|
|
202
|
+
direction: layout === 'vertical' ? 'column' : 'row',
|
|
203
|
+
children: [/*#__PURE__*/_jsx(ImageContainer, { ...themeTokens,
|
|
204
|
+
children: renderThumbnailImage(themeTokens)
|
|
205
|
+
}), renderThumbnailInfo(themeTokens)]
|
|
206
|
+
});
|
|
207
|
+
}
|
|
166
208
|
}, video.videoId);
|
|
167
209
|
};
|
|
168
210
|
|
|
@@ -30,7 +30,7 @@ const VideoSlider = _ref => {
|
|
|
30
30
|
setContainerWidth(width);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
const itemsGap =
|
|
33
|
+
const itemsGap = 32; // '5' on spacing scale
|
|
34
34
|
|
|
35
35
|
const itemsCount = viewport === 'lg' || viewport === 'xl' ? 4 : 3;
|
|
36
36
|
const itemGapPortioned = (itemsCount - 1) * itemsGap / itemsCount;
|
|
@@ -40,7 +40,7 @@ const VideoSlider = _ref => {
|
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
const content = /*#__PURE__*/_jsx(StackView, {
|
|
43
|
-
space:
|
|
43
|
+
space: 5,
|
|
44
44
|
direction: "row",
|
|
45
45
|
accessibilityRole: "radiogroup",
|
|
46
46
|
tokens: {
|
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.
|
|
9
|
-
"@telus-uds/system-constants": "^1.
|
|
8
|
+
"@telus-uds/components-base": "1.55.0",
|
|
9
|
+
"@telus-uds/system-constants": "^1.3.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.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^2.38.0",
|
|
16
16
|
"prop-types": "^15.7.2",
|
|
17
17
|
"lodash.throttle": "^4.1.1",
|
|
18
18
|
"react-youtube": "^10.1.0",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"skip": true
|
|
64
64
|
},
|
|
65
65
|
"types": "types/index.d.ts",
|
|
66
|
-
"version": "2.
|
|
66
|
+
"version": "2.14.0"
|
|
67
67
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
-
import { Box, StackView
|
|
3
|
+
import { Box, StackView } from '@telus-uds/components-base'
|
|
4
4
|
import Spinner from '../Spinner'
|
|
5
5
|
|
|
6
6
|
const Loading = ({ label }) => (
|
|
7
7
|
<Box space={3}>
|
|
8
8
|
<StackView direction="row" space={2} tokens={{ alignItems: 'center' }}>
|
|
9
|
-
<Spinner inline={true} show={true}
|
|
10
|
-
<Typography variant={{ size: 'small' }} accessibilityLiveRegion="polite">
|
|
11
|
-
{label}
|
|
12
|
-
</Typography>
|
|
9
|
+
<Spinner inline={true} show={true} label={label} labelPosition="right" />
|
|
13
10
|
</StackView>
|
|
14
11
|
</Box>
|
|
15
12
|
)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
en: {
|
|
3
3
|
hasResults: 'Some results are available',
|
|
4
|
-
loading: '
|
|
4
|
+
loading: 'Searching...',
|
|
5
5
|
noResults: 'No results found'
|
|
6
6
|
},
|
|
7
7
|
fr: {
|
|
8
8
|
hasResults: 'Quelques suggestions sont disponible',
|
|
9
|
-
loading: '
|
|
9
|
+
loading: 'Recherche...',
|
|
10
10
|
noResults: 'Aucun résultat trouvé'
|
|
11
11
|
}
|
|
12
12
|
}
|
package/src/Badge/Badge.jsx
CHANGED
|
@@ -42,7 +42,8 @@ const Badge = ({ children, tokens, variant = {}, ...rest }) => {
|
|
|
42
42
|
paddingTop,
|
|
43
43
|
paddingBottom,
|
|
44
44
|
fontName,
|
|
45
|
-
fontWeight
|
|
45
|
+
fontWeight,
|
|
46
|
+
fontSize
|
|
46
47
|
} = useThemeTokens('Badge', tokens, variant)
|
|
47
48
|
|
|
48
49
|
const semanticGradient = gradient && transformGradient(gradient)
|
|
@@ -56,6 +57,12 @@ const Badge = ({ children, tokens, variant = {}, ...rest }) => {
|
|
|
56
57
|
background = semanticGradient
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
const fontSizeMapping = {
|
|
61
|
+
12: 'micro',
|
|
62
|
+
14: 'small',
|
|
63
|
+
16: 'h6'
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
return (
|
|
60
67
|
<BadgeContainer
|
|
61
68
|
isOutlineOffer={isOutlineOffer}
|
|
@@ -69,7 +76,12 @@ const Badge = ({ children, tokens, variant = {}, ...rest }) => {
|
|
|
69
76
|
border={`${borderWidth}px solid ${borderColor}`}
|
|
70
77
|
{...selectProps(rest)}
|
|
71
78
|
>
|
|
72
|
-
<Typography
|
|
79
|
+
<Typography
|
|
80
|
+
tokens={{ fontName, fontWeight, color }}
|
|
81
|
+
variant={{ size: fontSizeMapping[fontSize] }}
|
|
82
|
+
>
|
|
83
|
+
{children}
|
|
84
|
+
</Typography>
|
|
73
85
|
</BadgeContainer>
|
|
74
86
|
)
|
|
75
87
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useEffect, useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import styled from 'styled-components'
|
|
4
4
|
import momentPropTypes from 'react-moment-proptypes'
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
applyTextStyles
|
|
16
16
|
} from '@telus-uds/components-base'
|
|
17
17
|
import moment from 'moment'
|
|
18
|
+
import { isUndefined } from 'lodash'
|
|
18
19
|
import CalendarContainer from './CalendarContainer'
|
|
19
20
|
import dictionary from './dictionary'
|
|
20
21
|
import { htmlAttrs } from '../utils'
|
|
@@ -43,6 +44,7 @@ const getResponsiveCircleSize = (inline = false, viewport = 'md') => {
|
|
|
43
44
|
|
|
44
45
|
return responsiveCircleSize
|
|
45
46
|
}
|
|
47
|
+
|
|
46
48
|
const MonthCenterContainer = styled.div({
|
|
47
49
|
display: 'flex',
|
|
48
50
|
justifyContent: 'center'
|
|
@@ -104,6 +106,16 @@ const DatePicker = forwardRef(
|
|
|
104
106
|
const [isFocused, setIsFocused] = useState(false)
|
|
105
107
|
const [isClickedInside, setIsClickedInside] = useState(false)
|
|
106
108
|
const getCopy = useCopy({ dictionary, copy })
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
/**
|
|
111
|
+
* `date` could be passed as `null` to reset the value so explicitly
|
|
112
|
+
* checking for not being `undefined`
|
|
113
|
+
*/
|
|
114
|
+
if (!isUndefined(date) && !moment(date).isSame(inputDate)) {
|
|
115
|
+
setInputDate(date)
|
|
116
|
+
setInputText(date instanceof moment ? date.format(dateFormat) : '')
|
|
117
|
+
}
|
|
118
|
+
}, [date, inputDate])
|
|
107
119
|
const onFocusChange = ({ focused }) => {
|
|
108
120
|
if (!isClickedInside) {
|
|
109
121
|
setIsFocused(focused)
|
|
@@ -132,6 +144,7 @@ const DatePicker = forwardRef(
|
|
|
132
144
|
const onChange = (value) => {
|
|
133
145
|
setInputDate(value)
|
|
134
146
|
setInputText(value.format(dateFormat))
|
|
147
|
+
setIsFocused(false)
|
|
135
148
|
if (onDateChange) onDateChange(value)
|
|
136
149
|
}
|
|
137
150
|
const onChangeInput = (value) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
-
import { Icon,
|
|
3
|
+
import { Icon, useResponsiveProp, useThemeTokens } from '@telus-uds/components-base'
|
|
4
4
|
import NavigationItem from './NavigationItem'
|
|
5
5
|
import Listbox from '../Listbox'
|
|
6
6
|
import useOverlaidPosition from '../utils/useOverlaidPosition'
|
|
@@ -61,12 +61,11 @@ const NavigationSubMenu = ({
|
|
|
61
61
|
>
|
|
62
62
|
{({ textStyles }) => [
|
|
63
63
|
children,
|
|
64
|
-
<Spacer key={`${id}_spacer`} space={1} direction="row" />,
|
|
65
64
|
<Icon
|
|
66
65
|
key={`${id}_icon`}
|
|
67
66
|
icon={icoMenu}
|
|
68
|
-
variant={{ size: '
|
|
69
|
-
tokens={{ color: textStyles[0]?.color
|
|
67
|
+
variant={{ size: 'micro' }}
|
|
68
|
+
tokens={{ color: textStyles[0]?.color }}
|
|
70
69
|
/>
|
|
71
70
|
]}
|
|
72
71
|
</NavigationItem>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import {
|
|
4
|
-
getThemeTokens,
|
|
5
4
|
Box,
|
|
6
5
|
TextInput,
|
|
7
6
|
Spacer,
|
|
@@ -9,13 +8,12 @@ import {
|
|
|
9
8
|
InputLabel,
|
|
10
9
|
useInputValue,
|
|
11
10
|
useCopy,
|
|
12
|
-
|
|
13
|
-
useTheme
|
|
11
|
+
useThemeTokensCallback
|
|
14
12
|
} from '@telus-uds/components-base'
|
|
15
13
|
|
|
16
|
-
import
|
|
17
|
-
import { InputField, InputWrapper, LeftButtonWrapper, RightButtonWrapper } from './styles'
|
|
14
|
+
import { InputField, InputWrapper } from './styles'
|
|
18
15
|
import defaultDictionary from './dictionary'
|
|
16
|
+
import SideButton from './SideButton'
|
|
19
17
|
|
|
20
18
|
const { isNaN } = Number
|
|
21
19
|
|
|
@@ -28,6 +26,7 @@ const QuantitySelector = ({
|
|
|
28
26
|
minNumber,
|
|
29
27
|
maxNumber,
|
|
30
28
|
defaultValue,
|
|
29
|
+
value,
|
|
31
30
|
label,
|
|
32
31
|
hint,
|
|
33
32
|
hintPosition,
|
|
@@ -40,13 +39,8 @@ const QuantitySelector = ({
|
|
|
40
39
|
tokens,
|
|
41
40
|
testID
|
|
42
41
|
}) => {
|
|
43
|
-
const {
|
|
44
|
-
components: { QuantitySelector: componentTheme }
|
|
45
|
-
} = useTheme()
|
|
46
|
-
|
|
47
|
-
const { leftIcon, rightIcon, padding } = useThemeTokens('QuantitySelector', tokens, variant)
|
|
42
|
+
const { disabled } = variant
|
|
48
43
|
const [error, setError] = useState('')
|
|
49
|
-
const { alternative } = variant
|
|
50
44
|
const getCopy = useCopy({ dictionary, copy })
|
|
51
45
|
|
|
52
46
|
const getValidatedNumber = (numberToEvaluate) => {
|
|
@@ -58,16 +52,14 @@ const QuantitySelector = ({
|
|
|
58
52
|
return numberToEvaluate
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
const initialValue = getValidatedNumber(defaultValue)
|
|
62
|
-
|
|
63
55
|
const { currentValue: number, setValue: setNumber } = useInputValue({
|
|
64
|
-
value:
|
|
65
|
-
initialValue,
|
|
56
|
+
value: getValidatedNumber(value),
|
|
57
|
+
initialValue: getValidatedNumber(defaultValue),
|
|
66
58
|
onChange
|
|
67
59
|
})
|
|
68
60
|
|
|
69
|
-
const isDecreaseEnabled = !isNumber(minNumber) || number > minNumber
|
|
70
|
-
const isIncreaseEnabled = !isNumber(maxNumber) || number < maxNumber
|
|
61
|
+
const isDecreaseEnabled = (!disabled && !isNumber(minNumber)) || number > minNumber
|
|
62
|
+
const isIncreaseEnabled = (!disabled && !isNumber(maxNumber)) || number < maxNumber
|
|
71
63
|
const inputValue = isNumber(number) ? number.toString() : ''
|
|
72
64
|
|
|
73
65
|
const updateNumber = (newNumber, originalInputEvent) => {
|
|
@@ -101,24 +93,34 @@ const QuantitySelector = ({
|
|
|
101
93
|
/>
|
|
102
94
|
) : null
|
|
103
95
|
|
|
96
|
+
const getTokens = useThemeTokensCallback('QuantitySelector', tokens, variant)
|
|
97
|
+
|
|
104
98
|
const renderTextInput = () => (
|
|
105
99
|
<TextInput
|
|
106
100
|
nativeID={id}
|
|
107
101
|
value={inputValue}
|
|
102
|
+
defaultValue={defaultValue}
|
|
108
103
|
tokens={(textInputState) => {
|
|
109
|
-
const {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
const {
|
|
105
|
+
inputWidth,
|
|
106
|
+
inputBorderWidth,
|
|
107
|
+
inputBorderColor,
|
|
108
|
+
textColor,
|
|
109
|
+
inputBackgroundColor,
|
|
110
|
+
...rest
|
|
111
|
+
} = getTokens({
|
|
112
|
+
...textInputState
|
|
113
|
+
})
|
|
116
114
|
return {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
...rest,
|
|
116
|
+
order: 1,
|
|
117
|
+
borderWidth: inputBorderWidth,
|
|
118
|
+
backgroundColor: inputBackgroundColor,
|
|
119
|
+
color: textColor,
|
|
120
|
+
width: inputWidth,
|
|
120
121
|
borderColor: inputBorderColor,
|
|
121
|
-
|
|
122
|
+
borderRadius: 0,
|
|
123
|
+
outerBorderWidth: 0
|
|
122
124
|
}
|
|
123
125
|
}}
|
|
124
126
|
onChange={inputChangeHandler}
|
|
@@ -133,58 +135,34 @@ const QuantitySelector = ({
|
|
|
133
135
|
/>
|
|
134
136
|
)
|
|
135
137
|
|
|
136
|
-
const getButtonTokens = (isEnabled) => (buttonState) => {
|
|
137
|
-
const disabled = !isEnabled
|
|
138
|
-
const { ...buttonTokens } = getThemeTokens(componentTheme, tokens, variant, {
|
|
139
|
-
...buttonState,
|
|
140
|
-
disabled
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
...buttonTokens,
|
|
145
|
-
outerBorderGap: 0,
|
|
146
|
-
padding
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const renderLeftButton = () => {
|
|
151
|
-
return (
|
|
152
|
-
<IconButton
|
|
153
|
-
icon={leftIcon}
|
|
154
|
-
tokens={getButtonTokens(isDecreaseEnabled)}
|
|
155
|
-
onPress={(event) => updateNumber(number - 1, event)}
|
|
156
|
-
onDoubleClick={(event) => updateNumber(number - 1, event)}
|
|
157
|
-
accessibilityLabel={getCopy('accessibility').decreaseButton}
|
|
158
|
-
accessibilityDisabled={!isDecreaseEnabled}
|
|
159
|
-
/>
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const renderRightButton = () => (
|
|
164
|
-
<IconButton
|
|
165
|
-
icon={rightIcon}
|
|
166
|
-
tokens={getButtonTokens(isIncreaseEnabled)}
|
|
167
|
-
onPress={() => updateNumber(number + 1)}
|
|
168
|
-
onDoubleClick={() => updateNumber(number + 1)}
|
|
169
|
-
accessibilityLabel={getCopy('accessibility').increaseButton}
|
|
170
|
-
accessibilityDisabled={!isIncreaseEnabled}
|
|
171
|
-
/>
|
|
172
|
-
)
|
|
173
|
-
|
|
174
138
|
return (
|
|
175
139
|
<Box space={2} testID={testID}>
|
|
176
140
|
{renderLabel()}
|
|
177
141
|
<Spacer space={2} />
|
|
178
142
|
<InputWrapper>
|
|
179
|
-
<InputField
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
143
|
+
<InputField>{renderTextInput()}</InputField>
|
|
144
|
+
<div style={{ order: 0 }}>
|
|
145
|
+
<SideButton
|
|
146
|
+
isEnabled={isDecreaseEnabled}
|
|
147
|
+
onPress={() => updateNumber(number - 1)}
|
|
148
|
+
onDoubleClick={() => updateNumber(number - 1)}
|
|
149
|
+
tokens={tokens}
|
|
150
|
+
variant={{ decrease: true, ...variant }}
|
|
151
|
+
accessibilityLabel={getCopy('accessibility').decreaseButton}
|
|
152
|
+
accessibilityDisabled={!isDecreaseEnabled}
|
|
153
|
+
/>
|
|
154
|
+
</div>
|
|
155
|
+
<div style={{ order: 2 }}>
|
|
156
|
+
<SideButton
|
|
157
|
+
isEnabled={isIncreaseEnabled}
|
|
158
|
+
onPress={() => updateNumber(number + 1)}
|
|
159
|
+
onDoubleClick={() => updateNumber(number + 1)}
|
|
160
|
+
accessibilityLabel={getCopy('accessibility').increaseButton}
|
|
161
|
+
accessibilityDisabled={!isIncreaseEnabled}
|
|
162
|
+
tokens={tokens}
|
|
163
|
+
variant={{ increase: true, ...variant }}
|
|
164
|
+
/>
|
|
165
|
+
</div>
|
|
188
166
|
</InputWrapper>
|
|
189
167
|
{error ? (
|
|
190
168
|
<Box vertical={2}>
|
|
@@ -230,6 +208,11 @@ QuantitySelector.propTypes = {
|
|
|
230
208
|
* The default value of the input field
|
|
231
209
|
*/
|
|
232
210
|
defaultValue: PropTypes.number,
|
|
211
|
+
/**
|
|
212
|
+
* If the input's state is to be controlled by a parent component, use this prop
|
|
213
|
+
* together with the `onChange` to pass down and update the lifted state.
|
|
214
|
+
*/
|
|
215
|
+
value: PropTypes.number,
|
|
233
216
|
/**
|
|
234
217
|
* The label of the input field
|
|
235
218
|
*/
|
|
@@ -262,7 +245,8 @@ QuantitySelector.propTypes = {
|
|
|
262
245
|
*/
|
|
263
246
|
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr'])]),
|
|
264
247
|
variant: PropTypes.exact({
|
|
265
|
-
alternative: PropTypes.bool
|
|
248
|
+
alternative: PropTypes.bool,
|
|
249
|
+
disabled: PropTypes.bool
|
|
266
250
|
}),
|
|
267
251
|
tokens: PropTypes.oneOf([PropTypes.object, PropTypes.func]),
|
|
268
252
|
/**
|