@telus-uds/components-base 1.54.0 → 1.56.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 +31 -2
- package/component-docs.json +136 -54
- package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +6 -2
- package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +9 -8
- package/lib/Carousel/CarouselThumbnail.js +53 -26
- package/lib/Carousel/CarouselThumbnailNavigation.js +15 -6
- package/lib/IconButton/IconButton.js +41 -7
- package/lib/InputLabel/InputLabel.js +2 -1
- package/lib/Link/LinkBase.js +3 -3
- package/lib/Select/Select.js +3 -2
- package/lib/ThemeProvider/utils/styles.js +18 -2
- package/lib/TooltipButton/TooltipButton.js +4 -2
- package/lib-module/Carousel/CarouselStepTracker/CarouselStepTracker.js +6 -2
- package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +9 -8
- package/lib-module/Carousel/CarouselThumbnail.js +51 -27
- package/lib-module/Carousel/CarouselThumbnailNavigation.js +13 -6
- package/lib-module/IconButton/IconButton.js +41 -7
- package/lib-module/InputLabel/InputLabel.js +2 -1
- package/lib-module/Link/LinkBase.js +3 -3
- package/lib-module/Select/Select.js +3 -2
- package/lib-module/ThemeProvider/utils/styles.js +19 -2
- package/lib-module/TooltipButton/TooltipButton.js +4 -2
- package/package.json +3 -3
- package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +10 -2
- package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +5 -5
- package/src/Carousel/CarouselThumbnail.jsx +31 -25
- package/src/Carousel/CarouselThumbnailNavigation.jsx +8 -3
- package/src/IconButton/IconButton.jsx +50 -6
- package/src/InputLabel/InputLabel.jsx +4 -1
- package/src/Link/LinkBase.jsx +3 -4
- package/src/Select/Select.jsx +3 -2
- package/src/ThemeProvider/utils/styles.js +29 -2
- package/src/TooltipButton/TooltipButton.jsx +5 -1
|
@@ -17,11 +17,6 @@ const CarouselTabsPanel = forwardRef(({ items }, ref) => {
|
|
|
17
17
|
const firstTabRef = useRef()
|
|
18
18
|
const [isInverse, setIsInverse] = useState(false)
|
|
19
19
|
|
|
20
|
-
// TODO: figure out a better cross-brand way to specify subcomponent variants.
|
|
21
|
-
// For now, this picks an Allium variant, and does nothing in brands that lack it.
|
|
22
|
-
// See similar comment in Carousel and https://github.com/telus/universal-design-system/issues/1549
|
|
23
|
-
const dividerVariant = { decorative: true }
|
|
24
|
-
|
|
25
20
|
const lastTabSelected = activeIndex === items.length - 1
|
|
26
21
|
|
|
27
22
|
// Get current select tab style
|
|
@@ -30,6 +25,11 @@ const CarouselTabsPanel = forwardRef(({ items }, ref) => {
|
|
|
30
25
|
setIsInverse(selectedVariantIsInverse?.inverse)
|
|
31
26
|
}, [items, activeIndex])
|
|
32
27
|
|
|
28
|
+
// TODO: figure out a better cross-brand way to specify subcomponent variants.
|
|
29
|
+
// For now, this picks an Allium variant, and does nothing in brands that lack it.
|
|
30
|
+
// See similar comment in Carousel and https://github.com/telus/universal-design-system/issues/1549
|
|
31
|
+
const dividerVariant = { decorative: true, inverse: isInverse }
|
|
32
|
+
|
|
33
33
|
return (
|
|
34
34
|
<View style={selectTabPanelStyle()}>
|
|
35
35
|
<StackView direction="row" space={3} divider={{ variant: dividerVariant }} ref={ref}>
|
|
@@ -2,14 +2,25 @@ import React from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { Pressable, Image } from 'react-native'
|
|
4
4
|
import { useCarousel } from './CarouselContext'
|
|
5
|
+
import { useThemeTokensCallback } from '../ThemeProvider'
|
|
6
|
+
import { useViewport } from '../ViewportProvider'
|
|
7
|
+
|
|
8
|
+
const selectPressableTokens = ({ borderColor, borderRadius, borderWidth, margin, padding }) => ({
|
|
9
|
+
borderColor,
|
|
10
|
+
borderRadius,
|
|
11
|
+
borderWidth,
|
|
12
|
+
margin,
|
|
13
|
+
padding
|
|
14
|
+
})
|
|
5
15
|
|
|
6
16
|
/**
|
|
7
17
|
* `Carousel.Thumbnail` is used to wrap the content of an individual slide and is suppsoed to be the
|
|
8
18
|
* only top-level component passed to the `Carousel`
|
|
9
19
|
*/
|
|
10
20
|
const CarouselThumbnail = ({ accessibilityLabel, alt, index, src }) => {
|
|
11
|
-
const { activeIndex, itemLabel, totalItems, getCopyWithPlaceholders, goTo
|
|
12
|
-
|
|
21
|
+
const { activeIndex, itemLabel, totalItems, getCopyWithPlaceholders, goTo } = useCarousel()
|
|
22
|
+
const getThumbnailTokens = useThemeTokensCallback('CarouselThumbnail')
|
|
23
|
+
const viewport = useViewport()
|
|
13
24
|
const thumbnailTitle =
|
|
14
25
|
alt ??
|
|
15
26
|
getCopyWithPlaceholders('stepTrackerLabel')
|
|
@@ -21,32 +32,17 @@ const CarouselThumbnail = ({ accessibilityLabel, alt, index, src }) => {
|
|
|
21
32
|
// Allow using the spacebar for navigation
|
|
22
33
|
if (event?.key === ' ') goTo(index)
|
|
23
34
|
}
|
|
24
|
-
const {
|
|
25
|
-
|
|
26
|
-
thumbnailBorderRadius,
|
|
27
|
-
thumbnailBorderWidth,
|
|
28
|
-
thumbnailMargin,
|
|
29
|
-
thumbnailPadding,
|
|
30
|
-
thumbnailSelectedBorderColor,
|
|
31
|
-
thumbnailSelectedBorderWidth,
|
|
32
|
-
thumbnailSize
|
|
33
|
-
} = themeTokens
|
|
35
|
+
const { borderWidth, padding, selectedBorderColor, selectedBorderWidth, size } =
|
|
36
|
+
getThumbnailTokens({ viewport })
|
|
34
37
|
const styles = {
|
|
35
|
-
pressable: {
|
|
36
|
-
borderColor: thumbnailBorderColor,
|
|
37
|
-
borderRadius: thumbnailBorderRadius,
|
|
38
|
-
borderWidth: thumbnailBorderWidth,
|
|
39
|
-
margin: thumbnailMargin,
|
|
40
|
-
padding: thumbnailPadding
|
|
41
|
-
},
|
|
42
38
|
image: {
|
|
43
|
-
height:
|
|
44
|
-
width:
|
|
39
|
+
height: size,
|
|
40
|
+
width: size
|
|
45
41
|
},
|
|
46
42
|
selected: {
|
|
47
|
-
borderColor:
|
|
48
|
-
borderWidth:
|
|
49
|
-
padding:
|
|
43
|
+
borderColor: selectedBorderColor,
|
|
44
|
+
borderWidth: selectedBorderWidth,
|
|
45
|
+
padding: padding - selectedBorderWidth + borderWidth
|
|
50
46
|
}
|
|
51
47
|
}
|
|
52
48
|
|
|
@@ -55,7 +51,17 @@ const CarouselThumbnail = ({ accessibilityLabel, alt, index, src }) => {
|
|
|
55
51
|
key={src}
|
|
56
52
|
onKeyDown={handleKeyDown}
|
|
57
53
|
onPress={handlePress}
|
|
58
|
-
style={
|
|
54
|
+
style={({ hovered, pressed, focused }) => {
|
|
55
|
+
const pressableStyles = selectPressableTokens(
|
|
56
|
+
getThumbnailTokens({
|
|
57
|
+
hover: hovered,
|
|
58
|
+
pressed,
|
|
59
|
+
focus: focused
|
|
60
|
+
})
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return [pressableStyles, index === activeIndex && styles.selected]
|
|
64
|
+
}}
|
|
59
65
|
>
|
|
60
66
|
<Image
|
|
61
67
|
accessibilityIgnoresInvertColors
|
|
@@ -4,19 +4,24 @@ import { View } from 'react-native'
|
|
|
4
4
|
import { useCarousel } from './CarouselContext'
|
|
5
5
|
import CarouselThumbnail from './CarouselThumbnail'
|
|
6
6
|
import { StackWrap } from '../StackView'
|
|
7
|
+
import { useThemeTokens } from '../ThemeProvider'
|
|
8
|
+
import { useViewport } from '../ViewportProvider'
|
|
7
9
|
|
|
8
10
|
const CarouselThumbnailNavigation = forwardRef(({ thumbnails = [] }, ref) => {
|
|
9
|
-
const
|
|
11
|
+
const viewport = useViewport()
|
|
12
|
+
const { alignItems } = useThemeTokens('CarouselThumbnail', {}, { viewport })
|
|
13
|
+
const { totalItems } = useCarousel()
|
|
10
14
|
if (thumbnails.length !== totalItems) {
|
|
11
15
|
throw new Error('Thumbnail set provided does not match the number of slides in the carousel')
|
|
12
16
|
}
|
|
13
|
-
const { thumbnailContainerPaddingTop, thumbnailMargin } =
|
|
17
|
+
const { containerPaddingTop: thumbnailContainerPaddingTop, margin: thumbnailMargin } =
|
|
18
|
+
useThemeTokens('CarouselThumbnail')
|
|
14
19
|
const stackWrapTokens = {
|
|
15
20
|
justifyContent: 'flex-start'
|
|
16
21
|
}
|
|
17
22
|
const containerStyles = {
|
|
18
23
|
justifyContent: 'center',
|
|
19
|
-
alignItems
|
|
24
|
+
alignItems,
|
|
20
25
|
paddingTop: thumbnailContainerPaddingTop - thumbnailMargin
|
|
21
26
|
}
|
|
22
27
|
|
|
@@ -22,27 +22,71 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
|
|
|
22
22
|
|
|
23
23
|
const selectOuterStyle = ({
|
|
24
24
|
backgroundColor,
|
|
25
|
-
borderRadius,
|
|
26
25
|
outerBorderWidth,
|
|
27
26
|
outerBorderColor,
|
|
28
27
|
outerBorderGap,
|
|
28
|
+
borderRadius,
|
|
29
|
+
borderTopLeftRadius,
|
|
30
|
+
borderTopRightRadius,
|
|
31
|
+
borderBottomLeftRadius,
|
|
32
|
+
borderBottomRightRadius,
|
|
29
33
|
shadow
|
|
30
34
|
}) => [
|
|
31
35
|
{
|
|
32
36
|
backgroundColor,
|
|
33
37
|
...applyShadowToken(shadow),
|
|
34
|
-
...applyOuterBorder({
|
|
38
|
+
...applyOuterBorder({
|
|
39
|
+
borderRadius,
|
|
40
|
+
borderTopLeftRadius,
|
|
41
|
+
borderTopRightRadius,
|
|
42
|
+
borderBottomLeftRadius,
|
|
43
|
+
borderBottomRightRadius,
|
|
44
|
+
outerBorderWidth,
|
|
45
|
+
outerBorderColor,
|
|
46
|
+
outerBorderGap
|
|
47
|
+
}),
|
|
35
48
|
...Platform.select({ web: { outline: 'none', display: 'inline-flex' } })
|
|
36
49
|
},
|
|
37
50
|
staticStyles.outer
|
|
38
51
|
]
|
|
39
52
|
|
|
40
|
-
const
|
|
53
|
+
const calculatePadding = (padding, borderWidth) => padding && Math.max(0, padding - borderWidth) // Stable size as border changes
|
|
54
|
+
|
|
55
|
+
const selectInnerStyle = ({
|
|
56
|
+
borderColor,
|
|
57
|
+
borderWidth,
|
|
58
|
+
borderTopLeftRadius,
|
|
59
|
+
borderTopRightRadius,
|
|
60
|
+
borderBottomLeftRadius,
|
|
61
|
+
borderBottomRightRadius,
|
|
62
|
+
borderRadius,
|
|
63
|
+
padding = 0,
|
|
64
|
+
borderTopWidth,
|
|
65
|
+
borderRightWidth,
|
|
66
|
+
borderBottomWidth,
|
|
67
|
+
borderLeftWidth,
|
|
68
|
+
paddingLeft,
|
|
69
|
+
paddingRight,
|
|
70
|
+
paddingTop,
|
|
71
|
+
paddingBottom
|
|
72
|
+
}) => ({
|
|
41
73
|
// Inner borders animate with the icon and should be treated like a themable feature of the icon
|
|
42
74
|
borderColor,
|
|
43
75
|
borderRadius,
|
|
44
76
|
borderWidth,
|
|
45
|
-
|
|
77
|
+
borderTopLeftRadius,
|
|
78
|
+
borderTopRightRadius,
|
|
79
|
+
borderBottomLeftRadius,
|
|
80
|
+
borderBottomRightRadius,
|
|
81
|
+
borderTopWidth,
|
|
82
|
+
borderRightWidth,
|
|
83
|
+
borderBottomWidth,
|
|
84
|
+
borderLeftWidth,
|
|
85
|
+
padding: calculatePadding(padding, borderWidth),
|
|
86
|
+
paddingLeft: calculatePadding(paddingLeft, borderLeftWidth),
|
|
87
|
+
paddingRight: calculatePadding(paddingRight, borderRightWidth),
|
|
88
|
+
paddingTop: calculatePadding(paddingTop, borderTopWidth),
|
|
89
|
+
paddingBottom: calculatePadding(paddingBottom, borderBottomWidth)
|
|
46
90
|
})
|
|
47
91
|
|
|
48
92
|
/**
|
|
@@ -90,7 +134,7 @@ const IconButton = forwardRef(
|
|
|
90
134
|
return (
|
|
91
135
|
<View style={selectInnerStyle(themeTokens)}>
|
|
92
136
|
<Icon
|
|
93
|
-
icon={IconComponent}
|
|
137
|
+
icon={IconComponent || themeTokens.icon}
|
|
94
138
|
title={selectedProps.accessibilityLabel}
|
|
95
139
|
tokens={selectTokens('Icon', themeTokens, 'icon')}
|
|
96
140
|
variant={variant}
|
|
@@ -111,7 +155,7 @@ IconButton.propTypes = {
|
|
|
111
155
|
/**
|
|
112
156
|
* Defines the icon to be rendered
|
|
113
157
|
*/
|
|
114
|
-
icon: PropTypes.elementType
|
|
158
|
+
icon: PropTypes.elementType,
|
|
115
159
|
/**
|
|
116
160
|
* URL to navigate to when the `Iconbutton` is pressed
|
|
117
161
|
*/
|
|
@@ -86,7 +86,10 @@ const InputLabel = forwardRef(
|
|
|
86
86
|
<View
|
|
87
87
|
style={[
|
|
88
88
|
staticStyles.tooltipAlign,
|
|
89
|
-
{
|
|
89
|
+
{
|
|
90
|
+
height: themeTokens.fontSize * themeTokens.lineHeight,
|
|
91
|
+
color: themeTokens.color
|
|
92
|
+
}
|
|
90
93
|
]}
|
|
91
94
|
>
|
|
92
95
|
<Tooltip content={tooltip} copy={copy} />
|
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -36,9 +36,9 @@ const selectOuterBorderStyles = ({
|
|
|
36
36
|
...applyOuterBorder({
|
|
37
37
|
outerBorderColor,
|
|
38
38
|
outerBorderWidth,
|
|
39
|
-
outerBorderGap
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
outerBorderGap
|
|
40
|
+
}),
|
|
41
|
+
borderRadius
|
|
42
42
|
}
|
|
43
43
|
: {}
|
|
44
44
|
|
|
@@ -156,7 +156,6 @@ const LinkBase = forwardRef(
|
|
|
156
156
|
const themeTokens = resolveLinkTokens(linkState)
|
|
157
157
|
const outerBorderStyles = selectOuterBorderStyles(themeTokens)
|
|
158
158
|
const decorationStyles = selectDecorationStyles(themeTokens)
|
|
159
|
-
|
|
160
159
|
return [
|
|
161
160
|
outerBorderStyles,
|
|
162
161
|
blockLeftStyle,
|
package/src/Select/Select.jsx
CHANGED
|
@@ -119,7 +119,8 @@ const selectIconTokens = ({ iconSize, iconColor }) => ({
|
|
|
119
119
|
})
|
|
120
120
|
|
|
121
121
|
const selectIconContainerStyles = ({ paddingRight, paddingBottom }) => ({
|
|
122
|
-
paddingRight,
|
|
122
|
+
paddingRight: paddingRight + 4,
|
|
123
|
+
marginRight: -4,
|
|
123
124
|
paddingBottom
|
|
124
125
|
})
|
|
125
126
|
|
|
@@ -134,7 +135,7 @@ const selectValidationIconContainerStyles = ({
|
|
|
134
135
|
paddingRight = 0,
|
|
135
136
|
paddingBottom
|
|
136
137
|
}) => ({
|
|
137
|
-
paddingRight: icon ? paddingRight + iconSize : paddingRight,
|
|
138
|
+
paddingRight: icon ? paddingRight + iconSize + 4 : paddingRight,
|
|
138
139
|
...(Platform.OS === 'android'
|
|
139
140
|
? {
|
|
140
141
|
paddingBottom: paddingBottom + ANDROID_VALIDATION_ICON_CONTAINER_OFFSET
|
|
@@ -147,6 +147,13 @@ export function verticalAlignRow(verticalAlign, reverse = false) {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
const calculateBorderRadius = (borderRadius, outerBorderGap, outerBorderWidth) => {
|
|
151
|
+
if (borderRadius) {
|
|
152
|
+
return borderRadius + outerBorderGap + outerBorderWidth
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return null
|
|
156
|
+
}
|
|
150
157
|
/**
|
|
151
158
|
* Use on an outer container to create an outer border with an optional gap around it
|
|
152
159
|
* that matches the border radius of any inner border.
|
|
@@ -155,11 +162,31 @@ export const applyOuterBorder = ({
|
|
|
155
162
|
outerBorderColor,
|
|
156
163
|
outerBorderWidth = 0,
|
|
157
164
|
outerBorderGap = 0,
|
|
158
|
-
borderRadius
|
|
165
|
+
borderRadius,
|
|
166
|
+
borderTopLeftRadius,
|
|
167
|
+
borderTopRightRadius,
|
|
168
|
+
borderBottomLeftRadius,
|
|
169
|
+
borderBottomRightRadius
|
|
159
170
|
}) => ({
|
|
160
171
|
margin: 0 - outerBorderWidth - outerBorderGap,
|
|
161
172
|
padding: outerBorderGap,
|
|
162
|
-
borderRadius: borderRadius
|
|
173
|
+
borderRadius: calculateBorderRadius(borderRadius, outerBorderGap, outerBorderWidth),
|
|
174
|
+
borderTopLeftRadius: calculateBorderRadius(borderTopLeftRadius, outerBorderGap, outerBorderWidth),
|
|
175
|
+
borderTopRightRadius: calculateBorderRadius(
|
|
176
|
+
borderTopRightRadius,
|
|
177
|
+
outerBorderGap,
|
|
178
|
+
outerBorderWidth
|
|
179
|
+
),
|
|
180
|
+
borderBottomLeftRadius: calculateBorderRadius(
|
|
181
|
+
borderBottomLeftRadius,
|
|
182
|
+
outerBorderGap,
|
|
183
|
+
outerBorderWidth
|
|
184
|
+
),
|
|
185
|
+
borderBottomRightRadius: calculateBorderRadius(
|
|
186
|
+
borderBottomRightRadius,
|
|
187
|
+
outerBorderGap,
|
|
188
|
+
outerBorderWidth
|
|
189
|
+
),
|
|
163
190
|
borderWidth: outerBorderWidth,
|
|
164
191
|
borderColor: outerBorderColor
|
|
165
192
|
})
|
|
@@ -7,7 +7,11 @@ import Icon from '../Icon'
|
|
|
7
7
|
|
|
8
8
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
9
9
|
|
|
10
|
-
const selectInnerContainerStyles = ({ borderRadius, width }) => ({
|
|
10
|
+
const selectInnerContainerStyles = ({ borderRadius, width, backgroundColor }) => ({
|
|
11
|
+
borderRadius,
|
|
12
|
+
width,
|
|
13
|
+
backgroundColor
|
|
14
|
+
})
|
|
11
15
|
|
|
12
16
|
const selectIconTokens = ({ iconSize, iconColor, iconScale = 1 }) => ({
|
|
13
17
|
size: iconSize,
|