@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.
Files changed (84) hide show
  1. package/CHANGELOG.md +41 -2
  2. package/component-docs.json +888 -66
  3. package/lib/Button/ButtonBase.js +36 -7
  4. package/lib/Button/ButtonGroup.js +7 -0
  5. package/lib/Button/propTypes.js +18 -0
  6. package/lib/Carousel/Carousel.js +69 -12
  7. package/lib/Carousel/CarouselContext.js +17 -11
  8. package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +73 -0
  9. package/lib/Carousel/CarouselTabs/CarouselTabs.js +70 -0
  10. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +95 -0
  11. package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +148 -0
  12. package/lib/Carousel/CarouselTabs/index.js +13 -0
  13. package/lib/Carousel/CarouselThumbnail.js +99 -0
  14. package/lib/Carousel/CarouselThumbnailNavigation.js +87 -0
  15. package/lib/Carousel/dictionary.js +4 -2
  16. package/lib/Carousel/index.js +10 -1
  17. package/lib/Checkbox/CheckboxGroup.js +7 -0
  18. package/lib/Icon/IconText.js +1 -1
  19. package/lib/Link/InlinePressable.js +1 -8
  20. package/lib/Link/LinkBase.js +6 -7
  21. package/lib/List/ListItem.js +1 -1
  22. package/lib/Notification/Notification.js +37 -22
  23. package/lib/Radio/RadioGroup.js +8 -0
  24. package/lib/RadioCard/RadioCardGroup.js +7 -0
  25. package/lib/SkipLink/SkipLink.js +216 -0
  26. package/lib/SkipLink/index.js +13 -0
  27. package/lib/ThemeProvider/ThemeProvider.js +6 -1
  28. package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  29. package/lib/index.js +9 -0
  30. package/lib-module/Button/ButtonBase.js +35 -7
  31. package/lib-module/Button/ButtonGroup.js +7 -0
  32. package/lib-module/Button/propTypes.js +17 -0
  33. package/lib-module/Carousel/Carousel.js +66 -11
  34. package/lib-module/Carousel/CarouselContext.js +17 -11
  35. package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +51 -0
  36. package/lib-module/Carousel/CarouselTabs/CarouselTabs.js +50 -0
  37. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +76 -0
  38. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanelItem.js +126 -0
  39. package/lib-module/Carousel/CarouselTabs/index.js +2 -0
  40. package/lib-module/Carousel/CarouselThumbnail.js +85 -0
  41. package/lib-module/Carousel/CarouselThumbnailNavigation.js +66 -0
  42. package/lib-module/Carousel/dictionary.js +4 -2
  43. package/lib-module/Carousel/index.js +2 -1
  44. package/lib-module/Checkbox/CheckboxGroup.js +7 -0
  45. package/lib-module/Icon/IconText.js +1 -1
  46. package/lib-module/Link/InlinePressable.js +1 -8
  47. package/lib-module/Link/LinkBase.js +6 -7
  48. package/lib-module/List/ListItem.js +1 -1
  49. package/lib-module/Notification/Notification.js +38 -23
  50. package/lib-module/Radio/RadioGroup.js +8 -0
  51. package/lib-module/RadioCard/RadioCardGroup.js +7 -0
  52. package/lib-module/SkipLink/SkipLink.js +188 -0
  53. package/lib-module/SkipLink/index.js +2 -0
  54. package/lib-module/ThemeProvider/ThemeProvider.js +5 -1
  55. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  56. package/lib-module/index.js +1 -0
  57. package/package.json +46 -47
  58. package/src/Button/ButtonBase.jsx +28 -9
  59. package/src/Button/ButtonGroup.jsx +6 -0
  60. package/src/Button/propTypes.js +14 -0
  61. package/src/Carousel/Carousel.jsx +68 -10
  62. package/src/Carousel/CarouselContext.jsx +22 -9
  63. package/src/Carousel/CarouselFirstFocus/CarouselFirstFocus.jsx +49 -0
  64. package/src/Carousel/CarouselTabs/CarouselTabs.jsx +37 -0
  65. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +69 -0
  66. package/src/Carousel/CarouselTabs/CarouselTabsPanelItem.jsx +119 -0
  67. package/src/Carousel/CarouselTabs/index.js +3 -0
  68. package/src/Carousel/CarouselThumbnail.jsx +77 -0
  69. package/src/Carousel/CarouselThumbnailNavigation.jsx +53 -0
  70. package/src/Carousel/dictionary.js +4 -2
  71. package/src/Carousel/index.js +1 -0
  72. package/src/Checkbox/CheckboxGroup.jsx +7 -0
  73. package/src/Icon/IconText.jsx +1 -1
  74. package/src/Link/InlinePressable.jsx +2 -8
  75. package/src/Link/LinkBase.jsx +8 -17
  76. package/src/List/ListItem.jsx +1 -1
  77. package/src/Notification/Notification.jsx +35 -20
  78. package/src/Radio/RadioGroup.jsx +7 -0
  79. package/src/RadioCard/RadioCardGroup.jsx +6 -0
  80. package/src/SkipLink/SkipLink.jsx +179 -0
  81. package/src/SkipLink/index.js +3 -0
  82. package/src/ThemeProvider/ThemeProvider.jsx +7 -1
  83. package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
  84. package/src/index.js +1 -0
@@ -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.func,
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, inline = false, ...props }, ref) => (
16
+ const InlinePressable = forwardRef(({ children, style, ...props }, ref) => (
19
17
  <Pressable
20
18
  ref={ref}
21
19
  style={(pressState) => [
22
- staticStyles[inline ? 'inline' : 'inlineFlex'],
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
 
@@ -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
- outerBorderWidth,
26
- outerBorderGap,
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.func,
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
  */
@@ -180,7 +180,7 @@ ListItem.propTypes = {
180
180
  /**
181
181
  * Renders side item icon
182
182
  */
183
- icon: PropTypes.func,
183
+ icon: PropTypes.elementType,
184
184
  /**
185
185
  * Will set display icon color
186
186
  */
@@ -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
- {IconComponent && (
125
- <View style={selectIconContainerStyles(themeTokens)}>
126
- <IconComponent {...selectIconProps(themeTokens)} />
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
- <View style={staticStyles.contentContainer}>
130
- {content && typeof content === 'function' ? content({ textStyles, variant }) : content}
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
- flex: 1
190
+ flexDirection: 'row',
191
+ flexShrink: 1
192
+ },
193
+ content: {
194
+ flexDirection: 'row',
195
+ flexShrink: 1,
196
+ justifyContent: 'space-between'
182
197
  }
183
198
  })
@@ -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)
@@ -0,0 +1,3 @@
1
+ import SkipLink from './SkipLink'
2
+
3
+ export default 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({ forceAbsoluteFontSizing: PropTypes.bool })
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'