@telus-uds/components-base 1.53.0 → 1.55.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 +32 -2
- package/component-docs.json +278 -74
- package/lib/Button/ButtonBase.js +17 -5
- 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/ExpandCollapse/Panel.js +65 -8
- package/lib/IconButton/IconButton.js +41 -7
- package/lib/Modal/Modal.js +9 -3
- package/lib/SkipLink/SkipLink.js +19 -15
- package/lib/ThemeProvider/utils/styles.js +18 -2
- package/lib/TooltipButton/TooltipButton.js +7 -3
- package/lib/Typography/Typography.js +11 -2
- package/lib-module/Button/ButtonBase.js +17 -5
- 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/ExpandCollapse/Panel.js +64 -8
- package/lib-module/IconButton/IconButton.js +41 -7
- package/lib-module/Modal/Modal.js +8 -3
- package/lib-module/SkipLink/SkipLink.js +19 -15
- package/lib-module/ThemeProvider/utils/styles.js +19 -2
- package/lib-module/TooltipButton/TooltipButton.js +7 -3
- package/lib-module/Typography/Typography.js +10 -2
- package/package.json +3 -3
- package/src/Button/ButtonBase.jsx +11 -1
- 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/ExpandCollapse/Panel.jsx +55 -8
- package/src/IconButton/IconButton.jsx +50 -6
- package/src/Modal/Modal.jsx +8 -3
- package/src/SkipLink/SkipLink.jsx +12 -12
- package/src/ThemeProvider/utils/styles.js +29 -2
- package/src/TooltipButton/TooltipButton.jsx +14 -2
- package/src/Typography/Typography.jsx +7 -2
|
@@ -54,7 +54,10 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
54
54
|
...rest
|
|
55
55
|
} = _ref2;
|
|
56
56
|
const viewport = useViewport();
|
|
57
|
-
const
|
|
57
|
+
const {
|
|
58
|
+
superScriptFontSize,
|
|
59
|
+
...themeTokens
|
|
60
|
+
} = useThemeTokens('Typography', tokens, variant, {
|
|
58
61
|
viewport
|
|
59
62
|
});
|
|
60
63
|
const {
|
|
@@ -77,8 +80,13 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
77
80
|
if (typeof child === 'object' && ((child === null || child === void 0 ? void 0 : child.type) === 'sub' || (child === null || child === void 0 ? void 0 : child.type) === 'sup')) {
|
|
78
81
|
var _child$props;
|
|
79
82
|
|
|
83
|
+
const childStyles = (child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.style) || {};
|
|
84
|
+
const supFontSize = childStyles.fontSize ?? superScriptFontSize;
|
|
80
85
|
const sanitizedChild = /*#__PURE__*/React.cloneElement(child, {
|
|
81
|
-
style: { ...
|
|
86
|
+
style: { ...childStyles,
|
|
87
|
+
...(supFontSize ? {
|
|
88
|
+
fontSize: supFontSize
|
|
89
|
+
} : {}),
|
|
82
90
|
lineHeight: 0
|
|
83
91
|
}
|
|
84
92
|
});
|
package/package.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"@floating-ui/react-dom": "^1.0.1",
|
|
11
11
|
"@floating-ui/react-native": "^0.8.1",
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
|
-
"@telus-uds/system-constants": "^1.
|
|
14
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
13
|
+
"@telus-uds/system-constants": "^1.3.0",
|
|
14
|
+
"@telus-uds/system-theme-tokens": "^2.38.0",
|
|
15
15
|
"airbnb-prop-types": "^2.16.0",
|
|
16
16
|
"lodash.debounce": "^4.0.8",
|
|
17
17
|
"lodash.merge": "^4.6.2",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"standard-engine": {
|
|
73
73
|
"skip": true
|
|
74
74
|
},
|
|
75
|
-
"version": "1.
|
|
75
|
+
"version": "1.55.0"
|
|
76
76
|
}
|
|
@@ -173,6 +173,13 @@ const selectWebOnlyStyles = (inactive, themeTokens, { accessibilityRole }) => {
|
|
|
173
173
|
})
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
const selectButtonStyles = ({ textAlign }) => {
|
|
177
|
+
return {
|
|
178
|
+
flexDirection: 'row',
|
|
179
|
+
justifyContent: textAlign
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
176
183
|
const selectItemIconTokens = ({ color, iconColor, iconSize }) => ({
|
|
177
184
|
size: iconSize,
|
|
178
185
|
color: iconColor || color
|
|
@@ -237,6 +244,8 @@ const ButtonBase = forwardRef(
|
|
|
237
244
|
const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align
|
|
238
245
|
const IconComponent = icon || themeTokens.icon
|
|
239
246
|
|
|
247
|
+
const rowStyles = selectButtonStyles(themeTokens)
|
|
248
|
+
|
|
240
249
|
return (
|
|
241
250
|
<View
|
|
242
251
|
id={id}
|
|
@@ -249,7 +258,8 @@ const ButtonBase = forwardRef(
|
|
|
249
258
|
web: {
|
|
250
259
|
maxWidth: '100%', // ensure overflowing content wraps
|
|
251
260
|
// TODO: https://github.com/telus/universal-design-system/issues/487
|
|
252
|
-
transition: 'background-color 200ms, border-color 200ms'
|
|
261
|
+
transition: 'background-color 200ms, border-color 200ms',
|
|
262
|
+
...rowStyles
|
|
253
263
|
}
|
|
254
264
|
})
|
|
255
265
|
]}
|
|
@@ -5,18 +5,26 @@ import StackView from '../../StackView'
|
|
|
5
5
|
import { variantProp } from '../../utils'
|
|
6
6
|
|
|
7
7
|
const CarouselStepTracker = ({ variant }) => {
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
activeIndex,
|
|
10
|
+
totalItems,
|
|
11
|
+
getCopyWithPlaceholders,
|
|
12
|
+
themeTokens: { stepTrackerCurrentBackgroundColor, ...themeTokens }
|
|
13
|
+
} = useCarousel()
|
|
9
14
|
const stackViewTokens = {
|
|
10
15
|
justifyContent: 'center'
|
|
11
16
|
}
|
|
17
|
+
|
|
12
18
|
const stepTrackerTokens = {
|
|
13
19
|
showStepLabel: false,
|
|
14
20
|
showStepTrackerLabel: true,
|
|
15
|
-
|
|
21
|
+
// TODO: StepTracker 'isComplete'/'isCurrent' is incorrect, see line StepTracker/Step.jsx line 63, refactor incorrect values and remove this
|
|
22
|
+
knobCompletedBackgroundColor: stepTrackerCurrentBackgroundColor ?? 'none',
|
|
16
23
|
connectorCompletedColor: 'none',
|
|
17
24
|
connectorColor: 'none',
|
|
18
25
|
containerPaddingTop: themeTokens.spaceBetweenSlideAndPanelNavigation
|
|
19
26
|
}
|
|
27
|
+
|
|
20
28
|
const steps = Array.from(Array(totalItems)).map((_, index) => String(index))
|
|
21
29
|
return (
|
|
22
30
|
<StackView direction="row" tokens={stackViewTokens}>
|
|
@@ -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
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef, useState } from 'react'
|
|
2
|
-
import { Animated, Platform, View } from 'react-native'
|
|
2
|
+
import { Animated, Platform, View, Text } from 'react-native'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
import ABBPropTypes from 'airbnb-prop-types'
|
|
5
5
|
|
|
@@ -26,7 +26,42 @@ const selectContainerStyles = ({
|
|
|
26
26
|
paddingLeft: contentPaddingLeft,
|
|
27
27
|
paddingRight: contentPaddingRight,
|
|
28
28
|
paddingTop: contentPaddingTop,
|
|
29
|
-
paddingBottom: contentPaddingBottom
|
|
29
|
+
paddingBottom: contentPaddingBottom,
|
|
30
|
+
flex: 1
|
|
31
|
+
})
|
|
32
|
+
const selectTextStyles = ({
|
|
33
|
+
contentPanelFontSize,
|
|
34
|
+
contentPanelFontName,
|
|
35
|
+
contentPanelFontColor,
|
|
36
|
+
contentPanelFontWeight,
|
|
37
|
+
contentPanelLineHeight
|
|
38
|
+
}) => ({
|
|
39
|
+
fontSize: contentPanelFontSize,
|
|
40
|
+
fontFamily: `${contentPanelFontName}${contentPanelFontWeight}normal`,
|
|
41
|
+
lineHeight: contentPanelFontSize * contentPanelLineHeight,
|
|
42
|
+
color: contentPanelFontColor
|
|
43
|
+
})
|
|
44
|
+
const selectContentPanelStyles = ({
|
|
45
|
+
contentPanelBackgroundColor,
|
|
46
|
+
contentPanelPaddingTop,
|
|
47
|
+
contentPanelPaddingBottom,
|
|
48
|
+
contentPanelPaddingLeft,
|
|
49
|
+
contentPanelPaddingRight,
|
|
50
|
+
contentPanelBorderWidth,
|
|
51
|
+
contentPanelBorderColor,
|
|
52
|
+
borderRadius,
|
|
53
|
+
marginBottom
|
|
54
|
+
}) => ({
|
|
55
|
+
backgroundColor: contentPanelBackgroundColor,
|
|
56
|
+
paddingTop: contentPanelPaddingTop,
|
|
57
|
+
paddingBottom: contentPanelPaddingBottom,
|
|
58
|
+
paddingLeft: contentPanelPaddingLeft,
|
|
59
|
+
paddingRight: contentPanelPaddingRight,
|
|
60
|
+
borderWidth: contentPanelBorderWidth,
|
|
61
|
+
borderColor: contentPanelBorderColor,
|
|
62
|
+
borderStyle: 'solid',
|
|
63
|
+
borderRadius,
|
|
64
|
+
marginBottom
|
|
30
65
|
})
|
|
31
66
|
|
|
32
67
|
/**
|
|
@@ -52,6 +87,7 @@ const ExpandCollapsePanel = forwardRef(
|
|
|
52
87
|
tokens,
|
|
53
88
|
variant,
|
|
54
89
|
controlRef,
|
|
90
|
+
content,
|
|
55
91
|
...rest
|
|
56
92
|
},
|
|
57
93
|
ref
|
|
@@ -90,8 +126,15 @@ const ExpandCollapsePanel = forwardRef(
|
|
|
90
126
|
})
|
|
91
127
|
|
|
92
128
|
const focusabilityProps = isExpanded ? {} : a11yProps.nonFocusableProps
|
|
93
|
-
|
|
94
|
-
|
|
129
|
+
return content ? (
|
|
130
|
+
<View style={selectContentPanelStyles(themeTokens)}>
|
|
131
|
+
{typeof children === 'string' ? (
|
|
132
|
+
<Text style={selectTextStyles(themeTokens)}>{children}</Text>
|
|
133
|
+
) : (
|
|
134
|
+
children
|
|
135
|
+
)}
|
|
136
|
+
</View>
|
|
137
|
+
) : (
|
|
95
138
|
<View ref={ref} style={themeTokens}>
|
|
96
139
|
<ExpandCollapseControl
|
|
97
140
|
{...selectedProps}
|
|
@@ -140,7 +183,7 @@ ExpandCollapsePanel.propTypes = {
|
|
|
140
183
|
* Function to call on pressing the panel's control, which should open or close the panel.
|
|
141
184
|
* If Panel is a direct child of `ExpandCollapse`, this prop will be provided by the ExpandCollapse parent.
|
|
142
185
|
*/
|
|
143
|
-
onToggle: PropTypes.func
|
|
186
|
+
onToggle: PropTypes.func,
|
|
144
187
|
/**
|
|
145
188
|
* Optional function to call on pressing the panel's control, in addition to opening or closing the panel.
|
|
146
189
|
*/
|
|
@@ -151,9 +194,9 @@ ExpandCollapsePanel.propTypes = {
|
|
|
151
194
|
*/
|
|
152
195
|
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
|
|
153
196
|
/**
|
|
154
|
-
* The content inside the
|
|
197
|
+
* The content inside the control element that opens and closes the ExpandCollapse when pressed.
|
|
155
198
|
*/
|
|
156
|
-
control: ExpandCollapseControl.propTypes.children
|
|
199
|
+
control: ExpandCollapseControl.propTypes.children,
|
|
157
200
|
/**
|
|
158
201
|
* Optional theme token overrides that may be passed to the ExpandCollapseControl element.
|
|
159
202
|
*/
|
|
@@ -161,7 +204,11 @@ ExpandCollapsePanel.propTypes = {
|
|
|
161
204
|
/**
|
|
162
205
|
* An optional ref to be attached to the control
|
|
163
206
|
*/
|
|
164
|
-
controlRef: ABBPropTypes.ref()
|
|
207
|
+
controlRef: ABBPropTypes.ref(),
|
|
208
|
+
/**
|
|
209
|
+
* A boolean prop to determine if the panel is a content panel or not. If true, the panel will not have a control
|
|
210
|
+
*/
|
|
211
|
+
content: PropTypes.bool
|
|
165
212
|
}
|
|
166
213
|
|
|
167
214
|
export default ExpandCollapsePanel
|
|
@@ -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
|
*/
|
package/src/Modal/Modal.jsx
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
StyleSheet,
|
|
4
4
|
TouchableWithoutFeedback,
|
|
5
5
|
View,
|
|
6
|
+
ScrollView,
|
|
6
7
|
Modal as NativeModal,
|
|
7
8
|
Platform
|
|
8
9
|
} from 'react-native'
|
|
@@ -114,7 +115,7 @@ const Modal = forwardRef(
|
|
|
114
115
|
|
|
115
116
|
return (
|
|
116
117
|
<NativeModal transparent {...selectProps(rest)}>
|
|
117
|
-
<
|
|
118
|
+
<ScrollView contentContainerStyle={[staticStyles.positioningContainer]} ref={modalRef}>
|
|
118
119
|
<View
|
|
119
120
|
style={[staticStyles.sizingContainer, selectContainerStyles(themeTokens)]}
|
|
120
121
|
pointerEvents="box-none" // don't capture backdrop press events
|
|
@@ -149,7 +150,7 @@ const Modal = forwardRef(
|
|
|
149
150
|
<TouchableWithoutFeedback onPress={handleClose}>
|
|
150
151
|
<View style={[staticStyles.backdrop, selectBackdropStyles(themeTokens)]} />
|
|
151
152
|
</TouchableWithoutFeedback>
|
|
152
|
-
</
|
|
153
|
+
</ScrollView>
|
|
153
154
|
</NativeModal>
|
|
154
155
|
)
|
|
155
156
|
}
|
|
@@ -210,7 +211,11 @@ const staticStyles = StyleSheet.create({
|
|
|
210
211
|
},
|
|
211
212
|
modal: {
|
|
212
213
|
maxHeight: '100%', // so that the modal can expand vertically up to the sizing container's height (exclusive of its vertical padding)
|
|
213
|
-
|
|
214
|
+
...Platform.select({
|
|
215
|
+
web: {
|
|
216
|
+
overflow: 'auto'
|
|
217
|
+
}
|
|
218
|
+
})
|
|
214
219
|
},
|
|
215
220
|
closeButtonContainer: {
|
|
216
221
|
position: 'absolute',
|
|
@@ -37,8 +37,12 @@ const selectStyles = ({
|
|
|
37
37
|
borderRadius
|
|
38
38
|
})
|
|
39
39
|
|
|
40
|
-
const selectTextStyles = ({ color }) => ({
|
|
41
|
-
color
|
|
40
|
+
const selectTextStyles = ({ color, textLine, fontName, fontSize, fontWeight, lineHeight }) => ({
|
|
41
|
+
color,
|
|
42
|
+
textDecorationLine: textLine,
|
|
43
|
+
fontFamily: `${fontName}${fontWeight}normal`,
|
|
44
|
+
lineHeight: fontSize * lineHeight,
|
|
45
|
+
fontSize
|
|
42
46
|
})
|
|
43
47
|
|
|
44
48
|
/**
|
|
@@ -100,9 +104,6 @@ const SkipLink = forwardRef(({ tokens, variant, href, children, ...rawRest }, re
|
|
|
100
104
|
const { onPress, ...rest } = clickProps.toPressProps(rawRest)
|
|
101
105
|
|
|
102
106
|
const getTokens = useThemeTokensCallback('SkipLink', tokens, variant)
|
|
103
|
-
const defaultTokens = getTokens()
|
|
104
|
-
|
|
105
|
-
const resolveLinkTokens = (pressState) => resolvePressableTokens(defaultTokens, pressState)
|
|
106
107
|
|
|
107
108
|
const handlePress = (event) => {
|
|
108
109
|
if (typeof onPress === 'function') onPress(event)
|
|
@@ -115,18 +116,17 @@ const SkipLink = forwardRef(({ tokens, variant, href, children, ...rawRest }, re
|
|
|
115
116
|
accessibilityRole="link"
|
|
116
117
|
onPress={handlePress}
|
|
117
118
|
href={href}
|
|
118
|
-
style={(
|
|
119
|
-
const themeTokens = getTokens
|
|
119
|
+
style={(pressableState) => {
|
|
120
|
+
const themeTokens = resolvePressableTokens(getTokens, pressableState)
|
|
120
121
|
const skipLinkStyle = selectStyles(themeTokens)
|
|
121
|
-
|
|
122
|
-
return [staticStyles.absolute, skipLinkStyle, !
|
|
122
|
+
const { focused } = pressableState
|
|
123
|
+
return [staticStyles.absolute, skipLinkStyle, !focused && staticStyles.hidden]
|
|
123
124
|
}}
|
|
124
125
|
{...selectProps(rest)}
|
|
125
126
|
>
|
|
126
|
-
{(
|
|
127
|
-
const themeTokens =
|
|
127
|
+
{(pressableState) => {
|
|
128
|
+
const themeTokens = resolvePressableTokens(getTokens, pressableState)
|
|
128
129
|
const textStyles = selectTextStyles(themeTokens)
|
|
129
|
-
|
|
130
130
|
return <Text style={[textStyles, staticStyles.baseline]}>{children}</Text>
|
|
131
131
|
}}
|
|
132
132
|
</Pressable>
|
|
@@ -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,
|
|
@@ -26,7 +30,15 @@ const TooltipButton = ({ pressableState, tokens, variant, ...rest }) => {
|
|
|
26
30
|
const { icon: IconComponent } = themeTokens
|
|
27
31
|
|
|
28
32
|
return (
|
|
29
|
-
<View
|
|
33
|
+
<View
|
|
34
|
+
style={[
|
|
35
|
+
applyOuterBorder(themeTokens),
|
|
36
|
+
themeTokens.outerBorderWidth && {
|
|
37
|
+
margin: -themeTokens.outerBorderWidth
|
|
38
|
+
}
|
|
39
|
+
]}
|
|
40
|
+
{...selectProps(rest)}
|
|
41
|
+
>
|
|
30
42
|
<View style={selectInnerContainerStyles(themeTokens)}>
|
|
31
43
|
{IconComponent && <Icon icon={IconComponent} tokens={selectIconTokens(themeTokens)} />}
|
|
32
44
|
</View>
|
|
@@ -59,7 +59,9 @@ const Typography = forwardRef(
|
|
|
59
59
|
ref
|
|
60
60
|
) => {
|
|
61
61
|
const viewport = useViewport()
|
|
62
|
-
const themeTokens = useThemeTokens('Typography', tokens, variant, {
|
|
62
|
+
const { superScriptFontSize, ...themeTokens } = useThemeTokens('Typography', tokens, variant, {
|
|
63
|
+
viewport
|
|
64
|
+
})
|
|
63
65
|
const { themeOptions } = useTheme()
|
|
64
66
|
|
|
65
67
|
const resolvedTextProps = {
|
|
@@ -80,9 +82,12 @@ const Typography = forwardRef(
|
|
|
80
82
|
|
|
81
83
|
const resetTagStyling = (child) => {
|
|
82
84
|
if (typeof child === 'object' && (child?.type === 'sub' || child?.type === 'sup')) {
|
|
85
|
+
const childStyles = child?.props?.style || {}
|
|
86
|
+
const supFontSize = childStyles.fontSize ?? superScriptFontSize
|
|
83
87
|
const sanitizedChild = React.cloneElement(child, {
|
|
84
88
|
style: {
|
|
85
|
-
...
|
|
89
|
+
...childStyles,
|
|
90
|
+
...(supFontSize ? { fontSize: supFontSize } : {}),
|
|
86
91
|
lineHeight: 0
|
|
87
92
|
}
|
|
88
93
|
})
|