@telus-uds/components-base 1.12.1 → 1.14.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 +41 -2
- package/component-docs.json +888 -66
- package/lib/Button/ButtonBase.js +36 -7
- package/lib/Button/ButtonGroup.js +7 -0
- package/lib/Button/propTypes.js +18 -0
- package/lib/Carousel/Carousel.js +69 -12
- package/lib/Carousel/CarouselContext.js +17 -11
- package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +73 -0
- package/lib/Carousel/CarouselTabs/CarouselTabs.js +70 -0
- package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +95 -0
- package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +148 -0
- package/lib/Carousel/CarouselTabs/index.js +13 -0
- package/lib/Carousel/CarouselThumbnail.js +99 -0
- package/lib/Carousel/CarouselThumbnailNavigation.js +87 -0
- package/lib/Carousel/dictionary.js +4 -2
- package/lib/Carousel/index.js +10 -1
- package/lib/Checkbox/CheckboxGroup.js +7 -0
- package/lib/Icon/IconText.js +1 -1
- package/lib/Link/InlinePressable.js +1 -8
- package/lib/Link/LinkBase.js +6 -7
- package/lib/List/ListItem.js +1 -1
- package/lib/Notification/Notification.js +37 -22
- package/lib/Radio/RadioGroup.js +8 -0
- package/lib/RadioCard/RadioCardGroup.js +7 -0
- package/lib/SkipLink/SkipLink.js +216 -0
- package/lib/SkipLink/index.js +13 -0
- package/lib/ThemeProvider/ThemeProvider.js +6 -1
- package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
- package/lib/index.js +9 -0
- package/lib-module/Button/ButtonBase.js +35 -7
- package/lib-module/Button/ButtonGroup.js +7 -0
- package/lib-module/Button/propTypes.js +17 -0
- package/lib-module/Carousel/Carousel.js +66 -11
- package/lib-module/Carousel/CarouselContext.js +17 -11
- package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +51 -0
- package/lib-module/Carousel/CarouselTabs/CarouselTabs.js +50 -0
- package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +76 -0
- package/lib-module/Carousel/CarouselTabs/CarouselTabsPanelItem.js +126 -0
- package/lib-module/Carousel/CarouselTabs/index.js +2 -0
- package/lib-module/Carousel/CarouselThumbnail.js +85 -0
- package/lib-module/Carousel/CarouselThumbnailNavigation.js +66 -0
- package/lib-module/Carousel/dictionary.js +4 -2
- package/lib-module/Carousel/index.js +2 -1
- package/lib-module/Checkbox/CheckboxGroup.js +7 -0
- package/lib-module/Icon/IconText.js +1 -1
- package/lib-module/Link/InlinePressable.js +1 -8
- package/lib-module/Link/LinkBase.js +6 -7
- package/lib-module/List/ListItem.js +1 -1
- package/lib-module/Notification/Notification.js +38 -23
- package/lib-module/Radio/RadioGroup.js +8 -0
- package/lib-module/RadioCard/RadioCardGroup.js +7 -0
- package/lib-module/SkipLink/SkipLink.js +188 -0
- package/lib-module/SkipLink/index.js +2 -0
- package/lib-module/ThemeProvider/ThemeProvider.js +5 -1
- package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
- package/lib-module/index.js +1 -0
- package/package.json +46 -47
- package/src/Button/ButtonBase.jsx +28 -9
- package/src/Button/ButtonGroup.jsx +6 -0
- package/src/Button/propTypes.js +14 -0
- package/src/Carousel/Carousel.jsx +68 -10
- package/src/Carousel/CarouselContext.jsx +22 -9
- package/src/Carousel/CarouselFirstFocus/CarouselFirstFocus.jsx +49 -0
- package/src/Carousel/CarouselTabs/CarouselTabs.jsx +37 -0
- package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +69 -0
- package/src/Carousel/CarouselTabs/CarouselTabsPanelItem.jsx +119 -0
- package/src/Carousel/CarouselTabs/index.js +3 -0
- package/src/Carousel/CarouselThumbnail.jsx +77 -0
- package/src/Carousel/CarouselThumbnailNavigation.jsx +53 -0
- package/src/Carousel/dictionary.js +4 -2
- package/src/Carousel/index.js +1 -0
- package/src/Checkbox/CheckboxGroup.jsx +7 -0
- package/src/Icon/IconText.jsx +1 -1
- package/src/Link/InlinePressable.jsx +2 -8
- package/src/Link/LinkBase.jsx +8 -17
- package/src/List/ListItem.jsx +1 -1
- package/src/Notification/Notification.jsx +35 -20
- package/src/Radio/RadioGroup.jsx +7 -0
- package/src/RadioCard/RadioCardGroup.jsx +6 -0
- package/src/SkipLink/SkipLink.jsx +179 -0
- package/src/SkipLink/index.js +3 -0
- package/src/ThemeProvider/ThemeProvider.jsx +7 -1
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
- package/src/index.js +1 -0
package/src/Icon/IconText.jsx
CHANGED
|
@@ -52,7 +52,7 @@ IconText.propTypes = {
|
|
|
52
52
|
/**
|
|
53
53
|
* A valid UDS icon component imported from a UDS palette.
|
|
54
54
|
*/
|
|
55
|
-
icon: PropTypes.
|
|
55
|
+
icon: PropTypes.elementType,
|
|
56
56
|
/**
|
|
57
57
|
* Props that will be passed to the icon component. By default the icon's `scalesWithText`
|
|
58
58
|
* prop will be set as "true" so that the icon continues to match the size of the text
|
|
@@ -9,17 +9,15 @@ import { Pressable, StyleSheet } from 'react-native'
|
|
|
9
9
|
* InlinePressable is an alternative to React Native's Pressable that works better when nested
|
|
10
10
|
* inline inside Text. It accepts the same props as React Native's Pressable.
|
|
11
11
|
*
|
|
12
|
-
* On Web it simply passes its props to Pressable and defaults to `inline-flex` instead of `flex`.
|
|
13
|
-
*
|
|
14
12
|
* @param {PressableProps} PressableProps
|
|
15
13
|
*/
|
|
16
14
|
// React Native exports prop Types but not propTypes, use JSDoc types here rather than duplicate RN
|
|
17
15
|
// eslint-disable-next-line react/prop-types
|
|
18
|
-
const InlinePressable = forwardRef(({ children, style,
|
|
16
|
+
const InlinePressable = forwardRef(({ children, style, ...props }, ref) => (
|
|
19
17
|
<Pressable
|
|
20
18
|
ref={ref}
|
|
21
19
|
style={(pressState) => [
|
|
22
|
-
staticStyles
|
|
20
|
+
staticStyles.inline,
|
|
23
21
|
typeof style === 'function' ? style(pressState) : style
|
|
24
22
|
]}
|
|
25
23
|
{...props}
|
|
@@ -31,11 +29,7 @@ InlinePressable.displayName = 'InlinePressable'
|
|
|
31
29
|
|
|
32
30
|
const staticStyles = StyleSheet.create({
|
|
33
31
|
inline: {
|
|
34
|
-
// Stop Pressable defaulting to (block) flex
|
|
35
32
|
display: 'inline'
|
|
36
|
-
},
|
|
37
|
-
inlineFlex: {
|
|
38
|
-
display: 'inline-flex'
|
|
39
33
|
}
|
|
40
34
|
})
|
|
41
35
|
|
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -20,13 +20,10 @@ import { IconText, iconComponentPropTypes } from '../Icon'
|
|
|
20
20
|
|
|
21
21
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, linkProps, viewProps])
|
|
22
22
|
|
|
23
|
-
const selectOuterBorderStyles = (
|
|
24
|
-
outerBorderColor,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
borderRadius,
|
|
28
|
-
outerBorderOutline
|
|
29
|
-
}) =>
|
|
23
|
+
const selectOuterBorderStyles = (
|
|
24
|
+
{ outerBorderColor, outerBorderWidth, outerBorderGap, borderRadius, outerBorderOutline },
|
|
25
|
+
hasIcon
|
|
26
|
+
) =>
|
|
30
27
|
// A view wrapper with a border on native messes up inline text alignment
|
|
31
28
|
// so for now make focus styles strictly web-only
|
|
32
29
|
Platform.OS === 'web'
|
|
@@ -41,7 +38,7 @@ const selectOuterBorderStyles = ({
|
|
|
41
38
|
}),
|
|
42
39
|
// Stops focus ring stretching horizontally if parent has display: block
|
|
43
40
|
// width: fit-content isn't supported on Firefox; can't cascade props like CSS `width: fit-content; width: --moz-fit-content;`
|
|
44
|
-
display: 'inline-flex'
|
|
41
|
+
display: hasIcon ? 'inline-flex' : 'inline' // Stop Pressable defaulting to (block) flex
|
|
45
42
|
}
|
|
46
43
|
: {}
|
|
47
44
|
|
|
@@ -147,18 +144,12 @@ const LinkBase = forwardRef(
|
|
|
147
144
|
return (
|
|
148
145
|
<InlinePressable
|
|
149
146
|
{...selectedProps}
|
|
150
|
-
inline={hasIcon} // assuming links without icons should be inline (even if they are long)
|
|
151
147
|
ref={ref}
|
|
152
148
|
style={(linkState) => {
|
|
153
149
|
const themeTokens = resolveLinkTokens(linkState)
|
|
154
|
-
const outerBorderStyles = selectOuterBorderStyles(themeTokens)
|
|
150
|
+
const outerBorderStyles = selectOuterBorderStyles(themeTokens, hasIcon)
|
|
155
151
|
const decorationStyles = selectDecorationStyles(themeTokens)
|
|
156
|
-
return [
|
|
157
|
-
outerBorderStyles,
|
|
158
|
-
blockLeftStyle,
|
|
159
|
-
decorationStyles,
|
|
160
|
-
hasIcon && staticStyles.rowContainer
|
|
161
|
-
]
|
|
152
|
+
return [outerBorderStyles, blockLeftStyle, decorationStyles, staticStyles.rowContainer]
|
|
162
153
|
}}
|
|
163
154
|
>
|
|
164
155
|
{(linkState) => {
|
|
@@ -202,7 +193,7 @@ LinkBase.propTypes = {
|
|
|
202
193
|
* A function component for an SVG icon to render inside the link. Inherits size and color from
|
|
203
194
|
* the link and any Typography the link is nested inside.
|
|
204
195
|
*/
|
|
205
|
-
icon: PropTypes.
|
|
196
|
+
icon: PropTypes.elementType,
|
|
206
197
|
/**
|
|
207
198
|
* When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of Link.
|
|
208
199
|
*/
|
package/src/List/ListItem.jsx
CHANGED
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
selectTokens,
|
|
11
11
|
variantProp,
|
|
12
12
|
viewProps,
|
|
13
|
-
wrapStringsInText
|
|
13
|
+
wrapStringsInText,
|
|
14
|
+
useResponsiveProp
|
|
14
15
|
} from '../utils'
|
|
15
16
|
import ButtonBase from '../Button/ButtonBase'
|
|
16
17
|
import useCopy from '../utils/useCopy'
|
|
@@ -41,6 +42,10 @@ const selectDismissButtonContainerStyles = ({ dismissButtonGap }) => ({
|
|
|
41
42
|
paddingLeft: dismissButtonGap
|
|
42
43
|
})
|
|
43
44
|
|
|
45
|
+
const selectContentContainerStyle = (maxWidth) => ({
|
|
46
|
+
width: maxWidth || '100%'
|
|
47
|
+
})
|
|
48
|
+
|
|
44
49
|
/**
|
|
45
50
|
* A banner that highlights important messages:
|
|
46
51
|
* - Status message to show there is an error or outage of services
|
|
@@ -98,6 +103,7 @@ const Notification = forwardRef(
|
|
|
98
103
|
const themeTokens = useThemeTokens('Notification', tokens, variant, { system })
|
|
99
104
|
const getCopy = useCopy({ dictionary, copy })
|
|
100
105
|
const { themeOptions } = useTheme()
|
|
106
|
+
const contentMaxWidth = useResponsiveProp(themeOptions?.contentMaxWidth)
|
|
101
107
|
|
|
102
108
|
if (isDismissed) {
|
|
103
109
|
return null
|
|
@@ -121,25 +127,27 @@ const Notification = forwardRef(
|
|
|
121
127
|
style={[staticStyles.container, selectContainerStyles(themeTokens)]}
|
|
122
128
|
{...selectProps(rest)}
|
|
123
129
|
>
|
|
124
|
-
{
|
|
125
|
-
<View style={
|
|
126
|
-
|
|
130
|
+
<View style={[staticStyles.content, selectContentContainerStyle(contentMaxWidth)]}>
|
|
131
|
+
<View style={staticStyles.contentContainer}>
|
|
132
|
+
{IconComponent && (
|
|
133
|
+
<View style={selectIconContainerStyles(themeTokens)}>
|
|
134
|
+
<IconComponent {...selectIconProps(themeTokens)} />
|
|
135
|
+
</View>
|
|
136
|
+
)}
|
|
137
|
+
{content && typeof content === 'function' ? content({ textStyles, variant }) : content}
|
|
127
138
|
</View>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
{dismissible && DismissIconComponent && (
|
|
140
|
+
<View style={selectDismissButtonContainerStyles(themeTokens)}>
|
|
141
|
+
<ButtonBase
|
|
142
|
+
onPress={onDismissPress}
|
|
143
|
+
accessibilityRole="button"
|
|
144
|
+
accessibilityLabel={getCopy('dismiss')}
|
|
145
|
+
>
|
|
146
|
+
{() => <DismissIconComponent {...selectDismissIconProps(themeTokens)} />}
|
|
147
|
+
</ButtonBase>
|
|
148
|
+
</View>
|
|
149
|
+
)}
|
|
131
150
|
</View>
|
|
132
|
-
{dismissible && DismissIconComponent && (
|
|
133
|
-
<View style={selectDismissButtonContainerStyles(themeTokens)}>
|
|
134
|
-
<ButtonBase
|
|
135
|
-
onPress={onDismissPress}
|
|
136
|
-
accessibilityRole="button"
|
|
137
|
-
accessibilityLabel={getCopy('dismiss')}
|
|
138
|
-
>
|
|
139
|
-
{() => <DismissIconComponent {...selectDismissIconProps(themeTokens)} />}
|
|
140
|
-
</ButtonBase>
|
|
141
|
-
</View>
|
|
142
|
-
)}
|
|
143
151
|
</View>
|
|
144
152
|
)
|
|
145
153
|
}
|
|
@@ -175,9 +183,16 @@ export default Notification
|
|
|
175
183
|
|
|
176
184
|
const staticStyles = StyleSheet.create({
|
|
177
185
|
container: {
|
|
178
|
-
flexDirection: 'row'
|
|
186
|
+
flexDirection: 'row',
|
|
187
|
+
justifyContent: 'center'
|
|
179
188
|
},
|
|
180
189
|
contentContainer: {
|
|
181
|
-
|
|
190
|
+
flexDirection: 'row',
|
|
191
|
+
flexShrink: 1
|
|
192
|
+
},
|
|
193
|
+
content: {
|
|
194
|
+
flexDirection: 'row',
|
|
195
|
+
flexShrink: 1,
|
|
196
|
+
justifyContent: 'space-between'
|
|
182
197
|
}
|
|
183
198
|
})
|
package/src/Radio/RadioGroup.jsx
CHANGED
|
@@ -84,6 +84,7 @@ const RadioGroup = forwardRef(
|
|
|
84
84
|
legend,
|
|
85
85
|
tooltip,
|
|
86
86
|
hint,
|
|
87
|
+
hintPosition = 'inline',
|
|
87
88
|
validation,
|
|
88
89
|
feedback,
|
|
89
90
|
initialCheckedId,
|
|
@@ -125,6 +126,7 @@ const RadioGroup = forwardRef(
|
|
|
125
126
|
|
|
126
127
|
return (
|
|
127
128
|
<Radio
|
|
129
|
+
error={validation === 'error'}
|
|
128
130
|
ref={itemRef}
|
|
129
131
|
key={radioId}
|
|
130
132
|
id={radioId}
|
|
@@ -149,6 +151,7 @@ const RadioGroup = forwardRef(
|
|
|
149
151
|
legend={legend}
|
|
150
152
|
tooltip={tooltip}
|
|
151
153
|
hint={hint}
|
|
154
|
+
hintPosition={hintPosition}
|
|
152
155
|
space={fieldSpace}
|
|
153
156
|
feedback={feedback}
|
|
154
157
|
inactive={inactive}
|
|
@@ -201,6 +204,10 @@ RadioGroup.propTypes = {
|
|
|
201
204
|
* Optional additional text giving more detail to help a user make a choice.
|
|
202
205
|
*/
|
|
203
206
|
hint: PropTypes.string,
|
|
207
|
+
/**
|
|
208
|
+
* Position of the hint relative to label. Use `below` to display a larger hint below the label.
|
|
209
|
+
*/
|
|
210
|
+
hintPosition: PropTypes.oneOf(['inline', 'below']),
|
|
204
211
|
/**
|
|
205
212
|
* Optional tooltip text content to include alongside the legend and hint.
|
|
206
213
|
*/
|
|
@@ -85,6 +85,7 @@ const RadioCardGroup = forwardRef(
|
|
|
85
85
|
legend,
|
|
86
86
|
tooltip,
|
|
87
87
|
hint,
|
|
88
|
+
hintPosition = 'inline',
|
|
88
89
|
validation,
|
|
89
90
|
feedback,
|
|
90
91
|
initialCheckedId,
|
|
@@ -127,6 +128,7 @@ const RadioCardGroup = forwardRef(
|
|
|
127
128
|
legend={legend}
|
|
128
129
|
tooltip={tooltip}
|
|
129
130
|
hint={hint}
|
|
131
|
+
hintPosition={hintPosition}
|
|
130
132
|
space={fieldSpace}
|
|
131
133
|
feedback={feedback}
|
|
132
134
|
inactive={inactive || readOnly}
|
|
@@ -208,6 +210,10 @@ RadioCardGroup.propTypes = {
|
|
|
208
210
|
* Optional additional text giving more detail to help a user make a choice.
|
|
209
211
|
*/
|
|
210
212
|
hint: PropTypes.string,
|
|
213
|
+
/**
|
|
214
|
+
* Position of the hint relative to label. Use `below` to display a larger hint below the label.
|
|
215
|
+
*/
|
|
216
|
+
hintPosition: PropTypes.oneOf(['inline', 'below']),
|
|
211
217
|
/**
|
|
212
218
|
* Optional tooltip text content to include alongside the legend and hint.
|
|
213
219
|
*/
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import { Platform, Pressable, StyleSheet, Text } from 'react-native'
|
|
3
|
+
import PropTypes from 'prop-types'
|
|
4
|
+
|
|
5
|
+
import { useThemeTokensCallback } from '../ThemeProvider'
|
|
6
|
+
import {
|
|
7
|
+
a11yProps,
|
|
8
|
+
clickProps,
|
|
9
|
+
getTokensPropType,
|
|
10
|
+
linkProps,
|
|
11
|
+
resolvePressableTokens,
|
|
12
|
+
selectSystemProps,
|
|
13
|
+
variantProp,
|
|
14
|
+
withLinkRouter
|
|
15
|
+
} from '../utils'
|
|
16
|
+
|
|
17
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, linkProps])
|
|
18
|
+
|
|
19
|
+
// ensure explicit selection of tokens
|
|
20
|
+
const selectStyles = ({
|
|
21
|
+
backgroundColor,
|
|
22
|
+
outlineColor,
|
|
23
|
+
outlineOffset,
|
|
24
|
+
outlineStyle,
|
|
25
|
+
outlineWidth,
|
|
26
|
+
paddingHorizontal,
|
|
27
|
+
paddingVertical,
|
|
28
|
+
borderRadius
|
|
29
|
+
}) => ({
|
|
30
|
+
backgroundColor,
|
|
31
|
+
outlineColor,
|
|
32
|
+
outlineOffset,
|
|
33
|
+
outlineStyle,
|
|
34
|
+
outlineWidth,
|
|
35
|
+
paddingHorizontal,
|
|
36
|
+
paddingVertical,
|
|
37
|
+
borderRadius
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const selectTextStyles = ({ color }) => ({
|
|
41
|
+
color
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A generic Skip link component, unstyled by default.
|
|
46
|
+
* A Skip link component help keyboard-only users, screen reader users to skip
|
|
47
|
+
* sections and navigate to the content they want.
|
|
48
|
+
*
|
|
49
|
+
* ## Component API
|
|
50
|
+
*
|
|
51
|
+
* For common uses, pass a `href` that is a # link to a DOM id that can be skipped to (web only).
|
|
52
|
+
*
|
|
53
|
+
* The element with this ID should be focusable, e.g. `<Box nativeID="skip-target" focusable>`.
|
|
54
|
+
*
|
|
55
|
+
* Other custom behaviour may be set by passing an `onPress` function, and routers may be integrated
|
|
56
|
+
* in the same way as other navigation-related components by passing a `LinkRouter`; but a # anchor
|
|
57
|
+
* href on web and/or a `targetRef` for cross-platform applications is the recommended approach.
|
|
58
|
+
*
|
|
59
|
+
* ## Visible styling
|
|
60
|
+
*
|
|
61
|
+
* When focused, the skip link shows as a visible element similar to a simplified ButtonLink using
|
|
62
|
+
* UDS theming. The `tokens` prop may be used to override these styles.
|
|
63
|
+
*
|
|
64
|
+
* To control the background of a skip link, the following tokens can be used:
|
|
65
|
+
*
|
|
66
|
+
* - `backgroundColor`
|
|
67
|
+
* *
|
|
68
|
+
* In order to control the color of the skip link text, the following tokens can be used:
|
|
69
|
+
*
|
|
70
|
+
* - `color`
|
|
71
|
+
*
|
|
72
|
+
* ### Padding
|
|
73
|
+
*
|
|
74
|
+
* The following padding tokens can be used:
|
|
75
|
+
*
|
|
76
|
+
* - `paddingHorizontal`
|
|
77
|
+
* - `paddingVertical`
|
|
78
|
+
*
|
|
79
|
+
* ### Outline
|
|
80
|
+
*
|
|
81
|
+
* The following tokens to control the outline:
|
|
82
|
+
*
|
|
83
|
+
* - `outlineColor`
|
|
84
|
+
* - `outlineOffset`
|
|
85
|
+
* - `outlineStyle`
|
|
86
|
+
* - `outlineWidth`
|
|
87
|
+
*
|
|
88
|
+
* ## Usability and A11y guidelines
|
|
89
|
+
*
|
|
90
|
+
* - The skip link component is visually hidden until a keyboard press activates it.
|
|
91
|
+
* - Usually, you should place the skip link immediately after the opening <body> tag.
|
|
92
|
+
* - This lets users bypass top-level navigation links and jump to the main content on a page.
|
|
93
|
+
* - Also consider using SkipLink before a complex feature containing many focusable elements.
|
|
94
|
+
*
|
|
95
|
+
* ## Accessibility
|
|
96
|
+
*
|
|
97
|
+
* Skip link supports all the common a11y and link props.
|
|
98
|
+
*/
|
|
99
|
+
const SkipLink = forwardRef(({ tokens, variant, href, children, ...rawRest }, ref) => {
|
|
100
|
+
const { onPress, ...rest } = clickProps.toPressProps(rawRest)
|
|
101
|
+
|
|
102
|
+
const getTokens = useThemeTokensCallback('SkipLink', tokens, variant)
|
|
103
|
+
const defaultTokens = getTokens()
|
|
104
|
+
|
|
105
|
+
const resolveLinkTokens = (pressState) => resolvePressableTokens(defaultTokens, pressState)
|
|
106
|
+
|
|
107
|
+
const handlePress = (event) => {
|
|
108
|
+
if (typeof onPress === 'function') onPress(event)
|
|
109
|
+
// TODO - support native apps with something based on refs and/or setAccessibilityFocus
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<Pressable
|
|
114
|
+
ref={ref}
|
|
115
|
+
accessibilityRole="link"
|
|
116
|
+
onPress={handlePress}
|
|
117
|
+
href={href}
|
|
118
|
+
style={({ focused: focus }) => {
|
|
119
|
+
const themeTokens = getTokens({ focus })
|
|
120
|
+
const skipLinkStyle = selectStyles(themeTokens)
|
|
121
|
+
|
|
122
|
+
return [staticStyles.absolute, skipLinkStyle, !focus && staticStyles.hidden]
|
|
123
|
+
}}
|
|
124
|
+
{...selectProps(rest)}
|
|
125
|
+
>
|
|
126
|
+
{(pressState) => {
|
|
127
|
+
const themeTokens = resolveLinkTokens(pressState)
|
|
128
|
+
const textStyles = selectTextStyles(themeTokens)
|
|
129
|
+
|
|
130
|
+
return <Text style={[textStyles, staticStyles.baseline]}>{children}</Text>
|
|
131
|
+
}}
|
|
132
|
+
</Pressable>
|
|
133
|
+
)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
SkipLink.displayName = 'SkipLink'
|
|
137
|
+
|
|
138
|
+
SkipLink.propTypes = {
|
|
139
|
+
...selectedSystemPropTypes,
|
|
140
|
+
/**
|
|
141
|
+
* The text content shown or read out when the SkipLink is focused, usually a string.
|
|
142
|
+
*/
|
|
143
|
+
children: PropTypes.node,
|
|
144
|
+
/**
|
|
145
|
+
* The target to skip to. Usually an anchor link to a section id (e.g. href="#main-section").
|
|
146
|
+
*/
|
|
147
|
+
href: PropTypes.string,
|
|
148
|
+
tokens: getTokensPropType('SkipLink'),
|
|
149
|
+
variant: variantProp.propType
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const staticStyles = StyleSheet.create({
|
|
153
|
+
baseline: {
|
|
154
|
+
alignSelf: 'baseline'
|
|
155
|
+
},
|
|
156
|
+
absolute: {
|
|
157
|
+
margin: 0,
|
|
158
|
+
position: 'absolute',
|
|
159
|
+
top: 0,
|
|
160
|
+
left: 0
|
|
161
|
+
},
|
|
162
|
+
hidden: {
|
|
163
|
+
overflow: 'hidden',
|
|
164
|
+
...Platform.select({
|
|
165
|
+
web: {
|
|
166
|
+
clip: 'rect(0 0 0 0)',
|
|
167
|
+
clipPath: 'inset(50%)'
|
|
168
|
+
},
|
|
169
|
+
default: {
|
|
170
|
+
// width / height of 0 would make it non-focusable
|
|
171
|
+
height: 1,
|
|
172
|
+
width: 1,
|
|
173
|
+
opacity: 0
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
export default withLinkRouter(SkipLink)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { createContext, useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { validateThemeTokensVersion } from './utils'
|
|
4
|
+
import responsiveProps from '../utils/props/responsiveProps'
|
|
4
5
|
|
|
5
6
|
export const uninitialisedError = new Error('Theme context used outside of ThemeProvider')
|
|
6
7
|
|
|
@@ -40,8 +41,13 @@ ThemeProvider.propTypes = {
|
|
|
40
41
|
* - `forceAbsoluteFontSizing`: available on web only; when set to true, allows
|
|
41
42
|
* using absolute font sizing (in pixels, doesn't scale) instead of the
|
|
42
43
|
* relative sizing (in `rem`, scales depending on the browser settings)
|
|
44
|
+
* - `contentMaxWidth`: allows configuration of the content max width to be used in components
|
|
45
|
+
* such as Footnote and Notification to avoid content to stretch width more then the page's width
|
|
43
46
|
*/
|
|
44
|
-
themeOptions: PropTypes.shape({
|
|
47
|
+
themeOptions: PropTypes.shape({
|
|
48
|
+
forceAbsoluteFontSizing: PropTypes.bool,
|
|
49
|
+
contentMaxWidth: responsiveProps.getTypeOptionallyByViewport(PropTypes.number)
|
|
50
|
+
})
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
export default ThemeProvider
|
|
@@ -40,6 +40,7 @@ const ToggleSwitchGroup = forwardRef(
|
|
|
40
40
|
inactive = false,
|
|
41
41
|
feedback,
|
|
42
42
|
hint,
|
|
43
|
+
hintPosition = 'inline',
|
|
43
44
|
tooltip,
|
|
44
45
|
legend,
|
|
45
46
|
name: inputGroupName,
|
|
@@ -130,6 +131,7 @@ const ToggleSwitchGroup = forwardRef(
|
|
|
130
131
|
legend={legend}
|
|
131
132
|
tooltip={tooltip}
|
|
132
133
|
hint={hint}
|
|
134
|
+
hintPosition={hintPosition}
|
|
133
135
|
space={fieldSpace}
|
|
134
136
|
feedback={feedback}
|
|
135
137
|
inactive={inactive}
|
|
@@ -205,6 +207,10 @@ ToggleSwitchGroup.propTypes = {
|
|
|
205
207
|
* Optional additional text giving more detail to help a user make a choice.
|
|
206
208
|
*/
|
|
207
209
|
hint: PropTypes.string,
|
|
210
|
+
/**
|
|
211
|
+
* Position of the hint relative to label. Use `below` to display a larger hint below the label.
|
|
212
|
+
*/
|
|
213
|
+
hintPosition: PropTypes.oneOf(['inline', 'below']),
|
|
208
214
|
/**
|
|
209
215
|
* Optional tooltip text content to include alongside the legend and hint.
|
|
210
216
|
*/
|
package/src/index.js
CHANGED
|
@@ -32,6 +32,7 @@ export { default as Search } from './Search'
|
|
|
32
32
|
export { default as Select } from './Select'
|
|
33
33
|
export { default as SideNav } from './SideNav'
|
|
34
34
|
export { default as Skeleton } from './Skeleton'
|
|
35
|
+
export { default as SkipLink } from './SkipLink'
|
|
35
36
|
export { default as Spacer } from './Spacer'
|
|
36
37
|
export { default as StackView } from './StackView'
|
|
37
38
|
export * from './StackView'
|