@telus-uds/components-base 1.10.0 → 1.12.1
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 +37 -3
- package/component-docs.json +413 -62
- package/lib/BaseProvider/index.js +7 -2
- package/lib/Button/ButtonBase.js +18 -14
- package/lib/Carousel/Carousel.js +92 -71
- package/lib/Carousel/CarouselContext.js +12 -4
- package/lib/Carousel/CarouselItem/CarouselItem.js +24 -9
- package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +56 -0
- package/lib/Carousel/CarouselStepTracker/index.js +13 -0
- package/lib/Carousel/dictionary.js +23 -0
- package/lib/Checkbox/Checkbox.js +7 -3
- package/lib/Checkbox/CheckboxGroup.js +1 -1
- package/lib/Feedback/Feedback.js +18 -10
- package/lib/Icon/IconText.js +5 -0
- package/lib/InputLabel/InputLabel.js +11 -5
- package/lib/InputSupports/InputSupports.js +10 -3
- package/lib/InputSupports/useInputSupports.js +3 -2
- package/lib/Link/LinkBase.js +7 -3
- package/lib/List/ListItem.js +7 -3
- package/lib/Modal/Modal.js +4 -0
- package/lib/Notification/Notification.js +7 -2
- package/lib/Pagination/Pagination.js +7 -3
- package/lib/RadioCard/RadioCard.js +6 -1
- package/lib/Select/Select.js +7 -3
- package/lib/Skeleton/Skeleton.js +1 -0
- package/lib/StepTracker/Step.js +8 -4
- package/lib/StepTracker/StepTracker.js +17 -13
- package/lib/Tabs/TabsItem.js +4 -0
- package/lib/TextInput/TextInput.js +3 -1
- package/lib/TextInput/TextInputBase.js +7 -3
- package/lib/ThemeProvider/ThemeProvider.js +20 -3
- package/lib/ThemeProvider/utils/styles.js +8 -1
- package/lib/ThemeProvider/utils/theme-tokens.js +1 -1
- package/lib/Typography/Typography.js +6 -2
- package/lib/index.js +9 -0
- package/lib/utils/index.js +9 -0
- package/lib/utils/props/clickProps.js +2 -2
- package/lib/utils/props/handlerProps.js +77 -31
- package/lib/utils/useScrollBlocking.js +66 -0
- package/lib/utils/useScrollBlocking.native.js +11 -0
- package/lib-module/BaseProvider/index.js +7 -2
- package/lib-module/Button/ButtonBase.js +7 -3
- package/lib-module/Carousel/Carousel.js +85 -70
- package/lib-module/Carousel/CarouselContext.js +11 -4
- package/lib-module/Carousel/CarouselItem/CarouselItem.js +25 -10
- package/lib-module/Carousel/CarouselStepTracker/CarouselStepTracker.js +42 -0
- package/lib-module/Carousel/CarouselStepTracker/index.js +2 -0
- package/lib-module/Carousel/dictionary.js +16 -0
- package/lib-module/Checkbox/Checkbox.js +8 -4
- package/lib-module/Checkbox/CheckboxGroup.js +1 -1
- package/lib-module/Feedback/Feedback.js +19 -11
- package/lib-module/Icon/IconText.js +5 -0
- package/lib-module/InputLabel/InputLabel.js +12 -6
- package/lib-module/InputSupports/InputSupports.js +10 -3
- package/lib-module/InputSupports/useInputSupports.js +3 -2
- package/lib-module/Link/LinkBase.js +8 -4
- package/lib-module/List/ListItem.js +8 -4
- package/lib-module/Modal/Modal.js +3 -0
- package/lib-module/Notification/Notification.js +8 -3
- package/lib-module/Pagination/Pagination.js +8 -4
- package/lib-module/RadioCard/RadioCard.js +7 -2
- package/lib-module/Select/Select.js +8 -4
- package/lib-module/Skeleton/Skeleton.js +1 -0
- package/lib-module/StepTracker/Step.js +9 -5
- package/lib-module/StepTracker/StepTracker.js +17 -14
- package/lib-module/Tabs/TabsItem.js +5 -1
- package/lib-module/TextInput/TextInput.js +3 -1
- package/lib-module/TextInput/TextInputBase.js +8 -4
- package/lib-module/ThemeProvider/ThemeProvider.js +20 -3
- package/lib-module/ThemeProvider/utils/styles.js +8 -1
- package/lib-module/ThemeProvider/utils/theme-tokens.js +1 -1
- package/lib-module/Typography/Typography.js +7 -3
- package/lib-module/index.js +1 -0
- package/lib-module/utils/index.js +1 -0
- package/lib-module/utils/props/clickProps.js +2 -2
- package/lib-module/utils/props/handlerProps.js +78 -31
- package/lib-module/utils/useScrollBlocking.js +58 -0
- package/lib-module/utils/useScrollBlocking.native.js +2 -0
- package/package.json +3 -3
- package/src/BaseProvider/index.jsx +6 -3
- package/src/Button/ButtonBase.jsx +8 -3
- package/src/Carousel/Carousel.jsx +106 -74
- package/src/Carousel/CarouselContext.jsx +15 -4
- package/src/Carousel/CarouselItem/CarouselItem.jsx +26 -8
- package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +36 -0
- package/src/Carousel/CarouselStepTracker/index.js +3 -0
- package/src/Carousel/dictionary.js +16 -0
- package/src/Checkbox/Checkbox.jsx +14 -11
- package/src/Checkbox/CheckboxGroup.jsx +1 -1
- package/src/Feedback/Feedback.jsx +14 -7
- package/src/Icon/IconText.jsx +2 -0
- package/src/InputLabel/InputLabel.jsx +13 -12
- package/src/InputSupports/InputSupports.jsx +18 -3
- package/src/InputSupports/useInputSupports.js +2 -2
- package/src/Link/LinkBase.jsx +10 -4
- package/src/List/ListItem.jsx +9 -4
- package/src/Modal/Modal.jsx +3 -1
- package/src/Notification/Notification.jsx +5 -3
- package/src/Pagination/Pagination.jsx +6 -4
- package/src/RadioCard/RadioCard.jsx +3 -2
- package/src/Select/Select.jsx +12 -3
- package/src/Skeleton/Skeleton.jsx +1 -0
- package/src/StepTracker/Step.jsx +12 -4
- package/src/StepTracker/StepTracker.jsx +20 -13
- package/src/Tabs/TabsItem.jsx +3 -2
- package/src/TextInput/TextInput.jsx +1 -1
- package/src/TextInput/TextInputBase.jsx +11 -3
- package/src/ThemeProvider/ThemeProvider.jsx +16 -3
- package/src/ThemeProvider/utils/styles.js +9 -1
- package/src/ThemeProvider/utils/theme-tokens.js +1 -1
- package/src/Typography/Typography.jsx +11 -12
- package/src/index.js +1 -0
- package/src/utils/index.js +1 -0
- package/src/utils/props/clickProps.js +2 -2
- package/src/utils/props/handlerProps.js +64 -16
- package/src/utils/useScrollBlocking.js +57 -0
- package/src/utils/useScrollBlocking.native.js +2 -0
|
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react'
|
|
|
2
2
|
import { StyleSheet, Text, View } from 'react-native'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
|
|
5
|
-
import { applyTextStyles, useThemeTokens } from '../ThemeProvider'
|
|
5
|
+
import { applyTextStyles, useTheme, useThemeTokens } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
a11yProps,
|
|
8
8
|
getTokensPropType,
|
|
@@ -17,21 +17,20 @@ import Tooltip from '../Tooltip'
|
|
|
17
17
|
|
|
18
18
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
19
19
|
|
|
20
|
-
const selectLabelStyles = (tokens) =>
|
|
20
|
+
const selectLabelStyles = (tokens, themeOptions) =>
|
|
21
|
+
applyTextStyles({ ...selectTokens('Typography', tokens), themeOptions })
|
|
21
22
|
|
|
22
|
-
const selectHintStyles = (
|
|
23
|
-
hintColor,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
hintFontWeight,
|
|
27
|
-
hintLineHeight
|
|
28
|
-
}) =>
|
|
23
|
+
const selectHintStyles = (
|
|
24
|
+
{ hintColor, hintFontName, hintFontSize, hintFontWeight, hintLineHeight },
|
|
25
|
+
themeOptions
|
|
26
|
+
) =>
|
|
29
27
|
applyTextStyles({
|
|
30
28
|
color: hintColor,
|
|
31
29
|
fontName: hintFontName,
|
|
32
30
|
fontSize: hintFontSize,
|
|
33
31
|
fontWeight: hintFontWeight,
|
|
34
|
-
lineHeight: hintLineHeight
|
|
32
|
+
lineHeight: hintLineHeight,
|
|
33
|
+
themeOptions
|
|
35
34
|
})
|
|
36
35
|
|
|
37
36
|
const selectGapStyles = ({ gap }) => ({ marginRight: gap })
|
|
@@ -57,12 +56,14 @@ const InputLabel = forwardRef(
|
|
|
57
56
|
const hasTooltip = tooltip !== undefined
|
|
58
57
|
const isHintInline = hintPosition === 'inline'
|
|
59
58
|
|
|
59
|
+
const { themeOptions } = useTheme()
|
|
60
|
+
|
|
60
61
|
return (
|
|
61
62
|
<>
|
|
62
63
|
<View ref={ref} style={staticStyles.container} {...selectProps(rest)}>
|
|
63
64
|
<Text
|
|
64
65
|
style={[
|
|
65
|
-
selectLabelStyles(themeTokens),
|
|
66
|
+
selectLabelStyles(themeTokens, themeOptions),
|
|
66
67
|
selectGapStyles(themeTokens),
|
|
67
68
|
staticStyles.label
|
|
68
69
|
]}
|
|
@@ -72,7 +73,7 @@ const InputLabel = forwardRef(
|
|
|
72
73
|
{hint && isHintInline && (
|
|
73
74
|
<Text
|
|
74
75
|
style={[
|
|
75
|
-
selectHintStyles(themeTokens),
|
|
76
|
+
selectHintStyles(themeTokens, themeOptions),
|
|
76
77
|
hasTooltip && selectGapStyles(themeTokens),
|
|
77
78
|
staticStyles.label
|
|
78
79
|
]}
|
|
@@ -9,7 +9,17 @@ import useInputSupports from './useInputSupports'
|
|
|
9
9
|
|
|
10
10
|
const InputSupports = forwardRef(
|
|
11
11
|
(
|
|
12
|
-
{
|
|
12
|
+
{
|
|
13
|
+
children,
|
|
14
|
+
copy = 'en',
|
|
15
|
+
label,
|
|
16
|
+
hint,
|
|
17
|
+
hintPosition = 'inline',
|
|
18
|
+
feedback,
|
|
19
|
+
tooltip,
|
|
20
|
+
validation,
|
|
21
|
+
nativeID
|
|
22
|
+
},
|
|
13
23
|
ref
|
|
14
24
|
) => {
|
|
15
25
|
const { space } = useThemeTokens('InputSupports')
|
|
@@ -18,7 +28,8 @@ const InputSupports = forwardRef(
|
|
|
18
28
|
feedback,
|
|
19
29
|
hint,
|
|
20
30
|
label,
|
|
21
|
-
validation
|
|
31
|
+
validation,
|
|
32
|
+
nativeID
|
|
22
33
|
})
|
|
23
34
|
|
|
24
35
|
return (
|
|
@@ -72,7 +83,11 @@ InputSupports.propTypes = {
|
|
|
72
83
|
/**
|
|
73
84
|
* Use to visually mark an input as valid or invalid.
|
|
74
85
|
*/
|
|
75
|
-
validation: PropTypes.oneOf(['error', 'success'])
|
|
86
|
+
validation: PropTypes.oneOf(['error', 'success']),
|
|
87
|
+
/**
|
|
88
|
+
* ID for DOM element on web
|
|
89
|
+
*/
|
|
90
|
+
nativeID: PropTypes.string
|
|
76
91
|
}
|
|
77
92
|
|
|
78
93
|
export default InputSupports
|
|
@@ -2,7 +2,7 @@ import useUniqueId from '../utils/useUniqueId'
|
|
|
2
2
|
|
|
3
3
|
const joinDefined = (array) => array.filter((item) => item !== undefined).join(' ')
|
|
4
4
|
|
|
5
|
-
const useInputSupports = ({ label, feedback, validation, hint }) => {
|
|
5
|
+
const useInputSupports = ({ label, feedback, validation, hint, nativeID }) => {
|
|
6
6
|
const hasValidationError = validation === 'error'
|
|
7
7
|
|
|
8
8
|
const inputId = useUniqueId('input')
|
|
@@ -20,7 +20,7 @@ const useInputSupports = ({ label, feedback, validation, hint }) => {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
return {
|
|
23
|
-
inputId,
|
|
23
|
+
inputId: nativeID || inputId,
|
|
24
24
|
hintId,
|
|
25
25
|
feedbackId,
|
|
26
26
|
a11yProps
|
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -15,7 +15,7 @@ import { resolvePressableTokens } from '../utils/pressability'
|
|
|
15
15
|
import { withLinkRouter } from '../utils'
|
|
16
16
|
|
|
17
17
|
import InlinePressable from './InlinePressable'
|
|
18
|
-
import { applyTextStyles, applyOuterBorder } from '../ThemeProvider'
|
|
18
|
+
import { applyTextStyles, applyOuterBorder, useTheme } from '../ThemeProvider'
|
|
19
19
|
import { IconText, iconComponentPropTypes } from '../Icon'
|
|
20
20
|
|
|
21
21
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, linkProps, viewProps])
|
|
@@ -55,12 +55,16 @@ const selectTextStyles = ({ color }) => ({
|
|
|
55
55
|
})
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
-
const selectBlockStyles = (
|
|
58
|
+
const selectBlockStyles = (
|
|
59
|
+
{ blockFontWeight, blockFontSize, blockLineHeight, blockFontName },
|
|
60
|
+
themeOptions
|
|
61
|
+
) =>
|
|
59
62
|
applyTextStyles({
|
|
60
63
|
fontWeight: blockFontWeight,
|
|
61
64
|
fontSize: blockFontSize,
|
|
62
65
|
lineHeight: blockLineHeight,
|
|
63
|
-
fontName: blockFontName
|
|
66
|
+
fontName: blockFontName,
|
|
67
|
+
themeOptions
|
|
64
68
|
})
|
|
65
69
|
|
|
66
70
|
const selectDecorationStyles = ({ color, textLine, textLineStyle }) => ({
|
|
@@ -138,6 +142,8 @@ const LinkBase = forwardRef(
|
|
|
138
142
|
// On web, this makes focus rings wrap only the link, not the entire block
|
|
139
143
|
const blockLeftStyle = Platform.OS === 'web' && staticStyles.blockLeft
|
|
140
144
|
|
|
145
|
+
const { themeOptions } = useTheme()
|
|
146
|
+
|
|
141
147
|
return (
|
|
142
148
|
<InlinePressable
|
|
143
149
|
{...selectedProps}
|
|
@@ -162,7 +168,7 @@ const LinkBase = forwardRef(
|
|
|
162
168
|
|
|
163
169
|
// TODO: may need to apply some smarter text inheritance here if inline to avoid native
|
|
164
170
|
// issues like double-application of line heights breaking align-items: baseline
|
|
165
|
-
const blockTextStyles = selectBlockStyles(themeTokens)
|
|
171
|
+
const blockTextStyles = selectBlockStyles(themeTokens, themeOptions)
|
|
166
172
|
|
|
167
173
|
const IconComponent = icon || themeTokens.icon
|
|
168
174
|
const { iconSpace } = themeTokens
|
package/src/List/ListItem.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react'
|
|
2
2
|
import { View, Platform, StyleSheet } from 'react-native'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
|
-
import { useThemeTokens, applyTextStyles } from '../ThemeProvider'
|
|
4
|
+
import { useTheme, useThemeTokens, applyTextStyles } from '../ThemeProvider'
|
|
5
5
|
import {
|
|
6
6
|
a11yProps,
|
|
7
7
|
getTokensPropType,
|
|
@@ -41,12 +41,16 @@ const selectBulletPositioningStyles = ({ itemIconSize }) => ({
|
|
|
41
41
|
height: itemIconSize
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
const selectItemStyles = (
|
|
44
|
+
const selectItemStyles = (
|
|
45
|
+
{ itemFontWeight, itemFontSize, itemLineHeight, itemFontName },
|
|
46
|
+
themeOptions
|
|
47
|
+
) =>
|
|
45
48
|
applyTextStyles({
|
|
46
49
|
fontWeight: itemFontWeight,
|
|
47
50
|
fontSize: itemFontSize,
|
|
48
51
|
lineHeight: itemLineHeight,
|
|
49
|
-
fontName: itemFontName
|
|
52
|
+
fontName: itemFontName,
|
|
53
|
+
themeOptions
|
|
50
54
|
})
|
|
51
55
|
|
|
52
56
|
const selectItemBlockStyles = ({ interItemMargin }) => ({
|
|
@@ -80,8 +84,9 @@ const ListItem = forwardRef(
|
|
|
80
84
|
ref
|
|
81
85
|
) => {
|
|
82
86
|
const themeTokens = useThemeTokens('List', tokens, variant)
|
|
87
|
+
const { themeOptions } = useTheme()
|
|
83
88
|
|
|
84
|
-
const itemStyles = selectItemStyles(themeTokens)
|
|
89
|
+
const itemStyles = selectItemStyles(themeTokens, themeOptions)
|
|
85
90
|
const itemBlockStyles = selectItemBlockStyles(themeTokens)
|
|
86
91
|
const dividerStyles = selectDividerStyles(themeTokens)
|
|
87
92
|
const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens)
|
package/src/Modal/Modal.jsx
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import { useViewport } from '../ViewportProvider'
|
|
23
23
|
import IconButton from '../IconButton'
|
|
24
24
|
import dictionary from './dictionary'
|
|
25
|
+
import useScrollBlocking from '../utils/useScrollBlocking'
|
|
25
26
|
|
|
26
27
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
27
28
|
|
|
@@ -89,6 +90,7 @@ const Modal = forwardRef(
|
|
|
89
90
|
({ children, isOpen, onClose, maxWidth, tokens, variant, copy, closeButton, ...rest }, ref) => {
|
|
90
91
|
const viewport = useViewport()
|
|
91
92
|
const themeTokens = useThemeTokens('Modal', tokens, variant, { viewport, maxWidth })
|
|
93
|
+
const modalRef = useScrollBlocking(isOpen)
|
|
92
94
|
|
|
93
95
|
const { closeIcon: CloseIconComponent } = themeTokens
|
|
94
96
|
|
|
@@ -113,7 +115,7 @@ const Modal = forwardRef(
|
|
|
113
115
|
|
|
114
116
|
return (
|
|
115
117
|
<NativeModal transparent {...selectProps(rest)}>
|
|
116
|
-
<View style={[staticStyles.positioningContainer]}>
|
|
118
|
+
<View style={[staticStyles.positioningContainer]} ref={modalRef}>
|
|
117
119
|
<View
|
|
118
120
|
style={[staticStyles.sizingContainer, selectContainerStyles(themeTokens)]}
|
|
119
121
|
pointerEvents="box-none" // don't capture backdrop press events
|
|
@@ -2,7 +2,7 @@ import React, { forwardRef, useState } from 'react'
|
|
|
2
2
|
import { StyleSheet, View } from 'react-native'
|
|
3
3
|
|
|
4
4
|
import PropTypes from 'prop-types'
|
|
5
|
-
import { applyTextStyles, useThemeTokens } from '../ThemeProvider'
|
|
5
|
+
import { applyTextStyles, useTheme, useThemeTokens } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
a11yProps,
|
|
8
8
|
getTokensPropType,
|
|
@@ -20,7 +20,8 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
|
|
|
20
20
|
|
|
21
21
|
const selectContainerStyles = (tokens) => ({ ...tokens })
|
|
22
22
|
|
|
23
|
-
const selectTextStyles = (tokens) =>
|
|
23
|
+
const selectTextStyles = (tokens, themeOptions) =>
|
|
24
|
+
applyTextStyles({ ...selectTokens('Typography', tokens), themeOptions })
|
|
24
25
|
|
|
25
26
|
const selectIconProps = ({ iconSize, iconColor }) => ({
|
|
26
27
|
size: iconSize,
|
|
@@ -96,12 +97,13 @@ const Notification = forwardRef(
|
|
|
96
97
|
const [isDismissed, setIsDismissed] = useState(false)
|
|
97
98
|
const themeTokens = useThemeTokens('Notification', tokens, variant, { system })
|
|
98
99
|
const getCopy = useCopy({ dictionary, copy })
|
|
100
|
+
const { themeOptions } = useTheme()
|
|
99
101
|
|
|
100
102
|
if (isDismissed) {
|
|
101
103
|
return null
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
const textStyles = selectTextStyles(themeTokens)
|
|
106
|
+
const textStyles = selectTextStyles(themeTokens, themeOptions)
|
|
105
107
|
|
|
106
108
|
const content = wrapStringsInText(
|
|
107
109
|
typeof children === 'function' ? children({ textStyles }) : children,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
viewProps,
|
|
12
12
|
withLinkRouter
|
|
13
13
|
} from '../utils'
|
|
14
|
-
import { applyTextStyles, useThemeTokens } from '../ThemeProvider'
|
|
14
|
+
import { applyTextStyles, useTheme, useThemeTokens } from '../ThemeProvider'
|
|
15
15
|
import { useViewport } from '../ViewportProvider'
|
|
16
16
|
import Box from '../Box'
|
|
17
17
|
|
|
@@ -21,13 +21,14 @@ import SideButton from './SideButton'
|
|
|
21
21
|
|
|
22
22
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
23
23
|
|
|
24
|
-
const selectTextStyles = ({ color, fontName, fontSize, fontWeight, lineHeight }) =>
|
|
24
|
+
const selectTextStyles = ({ color, fontName, fontSize, fontWeight, lineHeight }, themeOptions) =>
|
|
25
25
|
applyTextStyles({
|
|
26
26
|
color,
|
|
27
27
|
fontName,
|
|
28
28
|
fontSize,
|
|
29
29
|
fontWeight,
|
|
30
|
-
lineHeight
|
|
30
|
+
lineHeight,
|
|
31
|
+
themeOptions
|
|
31
32
|
})
|
|
32
33
|
|
|
33
34
|
const Pagination = forwardRef(
|
|
@@ -49,6 +50,7 @@ const Pagination = forwardRef(
|
|
|
49
50
|
const { truncateAbove, gap, ...themeTokens } = useThemeTokens('Pagination', tokens, variant, {
|
|
50
51
|
viewport
|
|
51
52
|
})
|
|
53
|
+
const { themeOptions } = useTheme()
|
|
52
54
|
|
|
53
55
|
const items = React.Children.toArray(children)
|
|
54
56
|
|
|
@@ -66,7 +68,7 @@ const Pagination = forwardRef(
|
|
|
66
68
|
truncateAbove
|
|
67
69
|
})
|
|
68
70
|
|
|
69
|
-
const ellipsisTextStyles = selectTextStyles(themeTokens)
|
|
71
|
+
const ellipsisTextStyles = selectTextStyles(themeTokens, themeOptions)
|
|
70
72
|
|
|
71
73
|
if (items.length === 0) {
|
|
72
74
|
return null
|
|
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { StyleSheet, Text, View } from 'react-native'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { applyTextStyles, useTheme, useThemeTokensCallback } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
a11yProps,
|
|
8
8
|
focusHandlerProps,
|
|
@@ -96,6 +96,7 @@ const RadioCard = forwardRef(
|
|
|
96
96
|
|
|
97
97
|
const getTokens = useThemeTokensCallback('RadioCard', tokens, variant)
|
|
98
98
|
const getCardTokens = (cardState) => selectPressableCardTokens(getTokens(cardState))
|
|
99
|
+
const { themeOptions } = useTheme()
|
|
99
100
|
|
|
100
101
|
return (
|
|
101
102
|
<PressableCardBase
|
|
@@ -112,7 +113,7 @@ const RadioCard = forwardRef(
|
|
|
112
113
|
const { radioSpace, contentSpace, ...themeTokens } = getTokens(cardState)
|
|
113
114
|
const radioTokens = selectRadioButtonTokens(themeTokens, 'radio')
|
|
114
115
|
const titleTokens = selectTokens('Typography', themeTokens)
|
|
115
|
-
const textStyle = applyTextStyles(titleTokens)
|
|
116
|
+
const textStyle = applyTextStyles({ ...titleTokens, themeOptions })
|
|
116
117
|
return (
|
|
117
118
|
<StackView direction="row" space={radioSpace}>
|
|
118
119
|
<View style={[staticStyles.alignWithText, { height: textStyle.lineHeight }]}>
|
package/src/Select/Select.jsx
CHANGED
|
@@ -2,7 +2,7 @@ import React, { forwardRef, useState } from 'react'
|
|
|
2
2
|
|
|
3
3
|
import { View, Platform, StyleSheet } from 'react-native'
|
|
4
4
|
import PropTypes from 'prop-types'
|
|
5
|
-
import { applyTextStyles, useThemeTokens, applyOuterBorder } from '../ThemeProvider'
|
|
5
|
+
import { applyTextStyles, useThemeTokens, applyOuterBorder, useTheme } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
a11yProps,
|
|
8
8
|
componentPropType,
|
|
@@ -43,6 +43,7 @@ const selectInputStyles = (
|
|
|
43
43
|
validationIconSize = 0,
|
|
44
44
|
height
|
|
45
45
|
},
|
|
46
|
+
themeOptions,
|
|
46
47
|
inactive
|
|
47
48
|
) => {
|
|
48
49
|
// Subtract border width from padding so overall input width/height doesn't
|
|
@@ -50,7 +51,13 @@ const selectInputStyles = (
|
|
|
50
51
|
const offsetBorder = (value) =>
|
|
51
52
|
typeof value === 'number' ? Math.max(0, value - borderWidth) : value
|
|
52
53
|
|
|
53
|
-
const textStyles = applyTextStyles({
|
|
54
|
+
const textStyles = applyTextStyles({
|
|
55
|
+
fontName,
|
|
56
|
+
fontSize,
|
|
57
|
+
lineHeight,
|
|
58
|
+
fontWeight,
|
|
59
|
+
themeOptions
|
|
60
|
+
})
|
|
54
61
|
|
|
55
62
|
const webStyles = Platform.select({
|
|
56
63
|
web: {
|
|
@@ -205,13 +212,15 @@ const Select = forwardRef(
|
|
|
205
212
|
|
|
206
213
|
const { icon: IconComponent, validationIcon: ValidationIconComponent } = themeTokens
|
|
207
214
|
|
|
215
|
+
const { themeOptions } = useTheme()
|
|
216
|
+
|
|
208
217
|
return (
|
|
209
218
|
<InputSupports {...supportsProps} {...selectedProps}>
|
|
210
219
|
{({ inputId, ...props }) => (
|
|
211
220
|
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
212
221
|
<Picker
|
|
213
222
|
ref={ref}
|
|
214
|
-
style={selectInputStyles(themeTokens, inactive)}
|
|
223
|
+
style={selectInputStyles(themeTokens, themeOptions, inactive)}
|
|
215
224
|
onFocus={handleFocus}
|
|
216
225
|
onBlur={handleBlur}
|
|
217
226
|
onMouseOver={handleMouseOver}
|
package/src/StepTracker/Step.jsx
CHANGED
|
@@ -4,7 +4,7 @@ import { StyleSheet, Text, View } from 'react-native'
|
|
|
4
4
|
import StackView from '../StackView'
|
|
5
5
|
import Icon from '../Icon'
|
|
6
6
|
import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils'
|
|
7
|
-
import { applyTextStyles } from '../ThemeProvider'
|
|
7
|
+
import { applyTextStyles, useTheme } from '../ThemeProvider'
|
|
8
8
|
|
|
9
9
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
10
10
|
|
|
@@ -95,6 +95,7 @@ const selectLabelStyles = (
|
|
|
95
95
|
labelFontName,
|
|
96
96
|
labelLineHeight
|
|
97
97
|
},
|
|
98
|
+
themeOptions,
|
|
98
99
|
isCurrent
|
|
99
100
|
) =>
|
|
100
101
|
applyTextStyles({
|
|
@@ -102,7 +103,8 @@ const selectLabelStyles = (
|
|
|
102
103
|
fontSize: labelFontSize,
|
|
103
104
|
lineHeight: labelLineHeight,
|
|
104
105
|
fontWeight: isCurrent ? labelCurrentFontWeight : labelFontWeight,
|
|
105
|
-
fontName: labelFontName
|
|
106
|
+
fontName: labelFontName,
|
|
107
|
+
themeOptions
|
|
106
108
|
})
|
|
107
109
|
const getStepTestID = (isCompleted, isCurrent) => {
|
|
108
110
|
let testID = 'StepTracker-Step'
|
|
@@ -125,6 +127,7 @@ const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens, .
|
|
|
125
127
|
const isCompleted = status > stepIndex
|
|
126
128
|
const isCurrent = status === stepIndex
|
|
127
129
|
const isActive = isCompleted || isCurrent
|
|
130
|
+
const { themeOptions } = useTheme()
|
|
128
131
|
|
|
129
132
|
return (
|
|
130
133
|
<StackView
|
|
@@ -158,7 +161,12 @@ const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens, .
|
|
|
158
161
|
{showStepLabel && (
|
|
159
162
|
<View style={[staticStyles.stepLabelContainer, selectLabelContainerStyles(tokens)]}>
|
|
160
163
|
{showStepName && (
|
|
161
|
-
<Text
|
|
164
|
+
<Text
|
|
165
|
+
style={[
|
|
166
|
+
staticStyles.centeredText,
|
|
167
|
+
selectLabelStyles(tokens, themeOptions, isCurrent)
|
|
168
|
+
]}
|
|
169
|
+
>
|
|
162
170
|
{name}
|
|
163
171
|
</Text>
|
|
164
172
|
)}
|
|
@@ -167,7 +175,7 @@ const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens, .
|
|
|
167
175
|
style={[
|
|
168
176
|
staticStyles.centeredText,
|
|
169
177
|
tokens.labelDirection === 'column' && staticStyles.wrappingLabel,
|
|
170
|
-
selectLabelStyles(tokens, isCurrent)
|
|
178
|
+
selectLabelStyles(tokens, themeOptions, isCurrent)
|
|
171
179
|
]}
|
|
172
180
|
>
|
|
173
181
|
{label}
|
|
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { StyleSheet, Text, View } from 'react-native'
|
|
4
4
|
import StackView from '../StackView'
|
|
5
|
-
import { applyTextStyles, useThemeTokens } from '../ThemeProvider'
|
|
5
|
+
import { applyTextStyles, useTheme, useThemeTokens } from '../ThemeProvider'
|
|
6
6
|
import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils'
|
|
7
7
|
import { useViewport } from '../ViewportProvider'
|
|
8
8
|
import useCopy from '../utils/useCopy'
|
|
@@ -25,19 +25,17 @@ const selectContainerStyles = ({
|
|
|
25
25
|
const selectStepTrackerLabelContainerStyles = ({ labelMarginTop }) => ({
|
|
26
26
|
marginTop: labelMarginTop
|
|
27
27
|
})
|
|
28
|
-
const selectStepTrackerLabelStyles = (
|
|
29
|
-
labelColor,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
labelFontName,
|
|
33
|
-
labelLineHeight
|
|
34
|
-
}) =>
|
|
28
|
+
const selectStepTrackerLabelStyles = (
|
|
29
|
+
{ labelColor, labelFontSize, labelFontWeight, labelFontName, labelLineHeight },
|
|
30
|
+
themeOptions
|
|
31
|
+
) =>
|
|
35
32
|
applyTextStyles({
|
|
36
33
|
color: labelColor,
|
|
37
34
|
fontSize: labelFontSize,
|
|
38
35
|
lineHeight: labelLineHeight,
|
|
39
36
|
fontWeight: labelFontWeight,
|
|
40
|
-
fontName: labelFontName
|
|
37
|
+
fontName: labelFontName,
|
|
38
|
+
themeOptions
|
|
41
39
|
})
|
|
42
40
|
|
|
43
41
|
/**
|
|
@@ -106,6 +104,7 @@ const StepTracker = forwardRef(
|
|
|
106
104
|
: ''
|
|
107
105
|
const getStepLabel = (index) =>
|
|
108
106
|
themeTokens.showStepLabel ? getCopy('stepLabel').replace('%{stepNumber}', index + 1) : ''
|
|
107
|
+
const { themeOptions } = useTheme()
|
|
109
108
|
if (!steps.length) return null
|
|
110
109
|
const selectedProps = selectProps({
|
|
111
110
|
accessibilityLabel: stepTrackerLabel,
|
|
@@ -145,7 +144,9 @@ const StepTracker = forwardRef(
|
|
|
145
144
|
selectStepTrackerLabelContainerStyles(themeTokens)
|
|
146
145
|
]}
|
|
147
146
|
>
|
|
148
|
-
<Text style={selectStepTrackerLabelStyles(themeTokens)}>
|
|
147
|
+
<Text style={selectStepTrackerLabelStyles(themeTokens, themeOptions)}>
|
|
148
|
+
{stepTrackerLabel}
|
|
149
|
+
</Text>
|
|
149
150
|
</View>
|
|
150
151
|
)}
|
|
151
152
|
</StackView>
|
|
@@ -155,13 +156,19 @@ const StepTracker = forwardRef(
|
|
|
155
156
|
)
|
|
156
157
|
StepTracker.displayName = 'StepTracker'
|
|
157
158
|
|
|
159
|
+
// If a language dictionary entry is provided, it must contain every key
|
|
160
|
+
const dictionaryContentShape = PropTypes.shape({
|
|
161
|
+
stepLabel: PropTypes.string.isRequired,
|
|
162
|
+
stepTrackerLabel: PropTypes.string.isRequired
|
|
163
|
+
})
|
|
164
|
+
|
|
158
165
|
StepTracker.propTypes = {
|
|
159
166
|
...selectedSystemPropTypes,
|
|
160
167
|
current: PropTypes.number,
|
|
161
|
-
copy: PropTypes.oneOf(['en', 'fr']),
|
|
168
|
+
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), dictionaryContentShape]),
|
|
162
169
|
dictionary: PropTypes.shape({
|
|
163
|
-
en:
|
|
164
|
-
fr:
|
|
170
|
+
en: dictionaryContentShape,
|
|
171
|
+
fr: dictionaryContentShape
|
|
165
172
|
}),
|
|
166
173
|
steps: PropTypes.arrayOf(PropTypes.string),
|
|
167
174
|
tokens: getTokensPropType('StepTracker'),
|
package/src/Tabs/TabsItem.jsx
CHANGED
|
@@ -2,7 +2,7 @@ import React, { forwardRef, useEffect } from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'
|
|
4
4
|
|
|
5
|
-
import { applyTextStyles, useThemeTokensCallback } from '../ThemeProvider'
|
|
5
|
+
import { applyTextStyles, useTheme, useThemeTokensCallback } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
a11yProps,
|
|
8
8
|
clickProps,
|
|
@@ -97,7 +97,7 @@ const TabsItem = forwardRef(
|
|
|
97
97
|
) => {
|
|
98
98
|
// Convert onClick etc to onPress etc if used in an integration
|
|
99
99
|
const { onPress, ...rest } = clickProps.toPressProps(rawRest)
|
|
100
|
-
|
|
100
|
+
const { themeOptions } = useTheme()
|
|
101
101
|
const getTokens = useThemeTokensCallback('TabsItem', tokens, variant)
|
|
102
102
|
const resolveTokens = (pressableState) =>
|
|
103
103
|
resolvePressableTokens(getTokens, pressableState, { selected })
|
|
@@ -165,6 +165,7 @@ const TabsItem = forwardRef(
|
|
|
165
165
|
const containerStyles = selectContainerStyles(themeTokens)
|
|
166
166
|
const textStyles = applyTextStyles({
|
|
167
167
|
...selectTokens('Typography', themeTokens),
|
|
168
|
+
themeOptions,
|
|
168
169
|
textAlign
|
|
169
170
|
})
|
|
170
171
|
|
|
@@ -51,7 +51,7 @@ const TextInput = forwardRef(({ tokens, variant = {}, ...rest }, ref) => {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
return (
|
|
54
|
-
<InputSupports {...supportsProps}>
|
|
54
|
+
<InputSupports nativeID={selectedProps.nativeID} {...supportsProps}>
|
|
55
55
|
{({ inputId, ...props }) => (
|
|
56
56
|
<TextInputBase ref={ref} {...inputProps} nativeID={inputId} {...props} />
|
|
57
57
|
)}
|
|
@@ -2,7 +2,7 @@ import React, { forwardRef, useEffect, useState } from 'react'
|
|
|
2
2
|
import { Platform, StyleSheet, TextInput as NativeTextInput, View } from 'react-native'
|
|
3
3
|
|
|
4
4
|
import PropTypes from 'prop-types'
|
|
5
|
-
import { applyTextStyles, useThemeTokens, applyOuterBorder } from '../ThemeProvider'
|
|
5
|
+
import { applyTextStyles, useTheme, useThemeTokens, applyOuterBorder } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
a11yProps,
|
|
8
8
|
getTokensPropType,
|
|
@@ -43,6 +43,7 @@ const selectInputStyles = (
|
|
|
43
43
|
width,
|
|
44
44
|
height
|
|
45
45
|
},
|
|
46
|
+
themeOptions,
|
|
46
47
|
inactive
|
|
47
48
|
) => {
|
|
48
49
|
// Subtract border width from padding so overall input width/height doesn't
|
|
@@ -50,7 +51,13 @@ const selectInputStyles = (
|
|
|
50
51
|
const offsetBorder = (value) =>
|
|
51
52
|
typeof value === 'number' ? Math.max(0, value - borderWidth) : value
|
|
52
53
|
|
|
53
|
-
const textStyles = applyTextStyles({
|
|
54
|
+
const textStyles = applyTextStyles({
|
|
55
|
+
fontName,
|
|
56
|
+
fontSize,
|
|
57
|
+
lineHeight,
|
|
58
|
+
fontWeight,
|
|
59
|
+
themeOptions
|
|
60
|
+
})
|
|
54
61
|
|
|
55
62
|
function linesToHeight(lines) {
|
|
56
63
|
const { lineHeight: absoluteLineHeight } = textStyles
|
|
@@ -197,7 +204,8 @@ const TextInputBase = forwardRef(
|
|
|
197
204
|
value: isControlled ? currentValue : undefined
|
|
198
205
|
}
|
|
199
206
|
|
|
200
|
-
const
|
|
207
|
+
const { themeOptions } = useTheme()
|
|
208
|
+
const nativeInputStyle = selectInputStyles({ ...themeTokens, height }, themeOptions, inactive)
|
|
201
209
|
|
|
202
210
|
return (
|
|
203
211
|
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
@@ -7,7 +7,12 @@ export const uninitialisedError = new Error('Theme context used outside of Theme
|
|
|
7
7
|
export const ThemeContext = createContext(uninitialisedError)
|
|
8
8
|
export const ThemeSetterContext = createContext(uninitialisedError)
|
|
9
9
|
|
|
10
|
-
const ThemeProvider = ({
|
|
10
|
+
const ThemeProvider = ({
|
|
11
|
+
children,
|
|
12
|
+
defaultTheme,
|
|
13
|
+
// TODO: switch `forceAbsoluteFontSizing` to be false by default in the next major version
|
|
14
|
+
themeOptions = { forceAbsoluteFontSizing: true }
|
|
15
|
+
}) => {
|
|
11
16
|
const [theme, setTheme] = useState(defaultTheme)
|
|
12
17
|
|
|
13
18
|
// Validate the theme tokens version on every render.
|
|
@@ -17,7 +22,7 @@ const ThemeProvider = ({ children, defaultTheme }) => {
|
|
|
17
22
|
|
|
18
23
|
return (
|
|
19
24
|
<ThemeSetterContext.Provider value={setTheme}>
|
|
20
|
-
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
|
|
25
|
+
<ThemeContext.Provider value={{ ...theme, themeOptions }}>{children}</ThemeContext.Provider>
|
|
21
26
|
</ThemeSetterContext.Provider>
|
|
22
27
|
)
|
|
23
28
|
}
|
|
@@ -28,7 +33,15 @@ ThemeProvider.propTypes = {
|
|
|
28
33
|
metadata: PropTypes.shape({
|
|
29
34
|
themeTokensVersion: PropTypes.string.isRequired
|
|
30
35
|
}).isRequired
|
|
31
|
-
}).isRequired
|
|
36
|
+
}).isRequired,
|
|
37
|
+
/**
|
|
38
|
+
* An object containing options allowing to customize the theming experience:
|
|
39
|
+
*
|
|
40
|
+
* - `forceAbsoluteFontSizing`: available on web only; when set to true, allows
|
|
41
|
+
* using absolute font sizing (in pixels, doesn't scale) instead of the
|
|
42
|
+
* relative sizing (in `rem`, scales depending on the browser settings)
|
|
43
|
+
*/
|
|
44
|
+
themeOptions: PropTypes.shape({ forceAbsoluteFontSizing: PropTypes.bool })
|
|
32
45
|
}
|
|
33
46
|
|
|
34
47
|
export default ThemeProvider
|
|
@@ -15,13 +15,21 @@ export function applyTextStyles({
|
|
|
15
15
|
fontWeight = '400',
|
|
16
16
|
fontName,
|
|
17
17
|
fontStyle = 'normal',
|
|
18
|
+
themeOptions = {
|
|
19
|
+
// TODO: switch `forceAbsoluteFontSizing` to be false by default in the next major version
|
|
20
|
+
forceAbsoluteFontSizing: true
|
|
21
|
+
},
|
|
18
22
|
...rest
|
|
19
23
|
}) {
|
|
20
24
|
const styles = { ...rest }
|
|
25
|
+
const { forceAbsoluteFontSizing } = themeOptions
|
|
21
26
|
|
|
22
27
|
if (fontSize) {
|
|
23
28
|
// If relative font sizes are needed, catch and calculate them here
|
|
24
|
-
styles.fontSize =
|
|
29
|
+
styles.fontSize =
|
|
30
|
+
Platform.OS === 'web' && !forceAbsoluteFontSizing
|
|
31
|
+
? `${fontSize / fontBasePixels}rem`
|
|
32
|
+
: fontSize
|
|
25
33
|
}
|
|
26
34
|
if (typeof lineHeight === 'number') {
|
|
27
35
|
// React Native expects absolute line heights but multipliers are better as design tokens
|