@telus-uds/components-base 0.0.2-prerelease.9 → 1.1.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/.eslintrc.js +9 -0
- package/.storybook/main.js +4 -0
- package/.storybook/preview.js +37 -0
- package/.ultra.cache.json +1 -1
- package/CHANGELOG.md +50 -0
- package/README.md +4 -2
- package/__fixtures__/test-utils.js +25 -0
- package/__fixtures__/testTheme.js +4 -2
- package/__tests__/Button/ButtonGroup.test.jsx +4 -5
- package/__tests__/Checkbox/Checkbox.test.jsx +2 -2
- package/__tests__/Checkbox/CheckboxGroup.test.jsx +4 -5
- package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
- package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
- package/__tests__/Link/LinkBase.test.jsx +0 -14
- package/__tests__/Radio/Radio.test.jsx +2 -2
- package/__tests__/Radio/RadioGroup.test.jsx +4 -5
- package/__tests__/RadioCard/RadioCard.test.jsx +2 -2
- package/__tests__/RadioCard/RadioCardGroup.test.jsx +4 -5
- package/__tests__/Search/Search.test.jsx +9 -8
- package/__tests__/Select/Select.test.jsx +3 -2
- package/__tests__/Tabs/Tabs.test.jsx +1 -161
- package/__tests__/Tags/Tags.test.jsx +4 -5
- package/__tests__/TextInput/TextArea.test.jsx +3 -2
- package/__tests__/TextInput/TextInputBase.test.jsx +10 -5
- package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
- package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
- package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
- package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
- package/__tests__/utils/children.test.jsx +128 -0
- package/__tests__/utils/input.test.js +1 -1
- package/__tests__/utils/semantics.test.jsx +43 -0
- package/babel.config.js +9 -16
- package/component-docs.json +10313 -0
- package/generate-component-docs.js +56 -0
- package/lib/A11yText/index.js +10 -5
- package/lib/ActivityIndicator/Spinner.js +16 -13
- package/lib/ActivityIndicator/Spinner.native.js +12 -8
- package/lib/Box/Box.js +103 -8
- package/lib/Button/Button.js +9 -8
- package/lib/Button/ButtonBase.js +14 -7
- package/lib/Button/ButtonGroup.js +25 -10
- package/lib/Button/ButtonLink.js +10 -7
- package/lib/Card/Card.js +2 -0
- package/lib/Card/CardBase.js +13 -5
- package/lib/Card/PressableCardBase.js +12 -8
- package/lib/Checkbox/Checkbox.js +25 -14
- package/lib/Checkbox/CheckboxGroup.js +22 -12
- package/lib/Divider/Divider.js +12 -7
- package/lib/ExpandCollapse/Accordion.js +10 -4
- package/lib/ExpandCollapse/Control.js +12 -6
- package/lib/ExpandCollapse/ExpandCollapse.js +10 -5
- package/lib/ExpandCollapse/Panel.js +8 -7
- package/lib/Feedback/Feedback.js +10 -5
- package/lib/Fieldset/Fieldset.js +10 -5
- package/lib/Fieldset/FieldsetContainer.js +10 -5
- package/lib/Fieldset/FieldsetContainer.native.js +10 -5
- package/lib/Fieldset/Legend.js +10 -5
- package/lib/Fieldset/Legend.native.js +10 -5
- package/lib/FlexGrid/Col/Col.js +8 -5
- package/lib/FlexGrid/FlexGrid.js +31 -6
- package/lib/FlexGrid/Row/Row.js +12 -5
- package/lib/{Tabs → HorizontalScroll}/HorizontalScroll.js +5 -4
- package/lib/{Tabs/TabsScrollButton.js → HorizontalScroll/HorizontalScrollButton.js} +14 -8
- package/lib/{Tabs → HorizontalScroll}/ScrollViewEnd.js +0 -0
- package/lib/{Tabs → HorizontalScroll}/ScrollViewEnd.native.js +0 -0
- package/lib/{Tabs → HorizontalScroll}/dictionary.js +0 -0
- package/lib/HorizontalScroll/index.js +35 -0
- package/lib/{Tabs → HorizontalScroll}/itemPositions.js +0 -0
- package/lib/Icon/Icon.js +16 -9
- package/lib/Icon/IconText.js +8 -7
- package/lib/IconButton/IconButton.js +10 -5
- package/lib/InputLabel/InputLabel.js +33 -5
- package/lib/InputLabel/LabelContent.js +22 -12
- package/lib/InputLabel/LabelContent.native.js +23 -5
- package/lib/InputSupports/InputSupports.js +10 -5
- package/lib/Link/ChevronLink.js +12 -5
- package/lib/Link/InlinePressable.js +10 -4
- package/lib/Link/InlinePressable.native.js +5 -4
- package/lib/Link/Link.js +12 -5
- package/lib/Link/LinkBase.js +12 -5
- package/lib/Link/TextButton.js +10 -5
- package/lib/List/List.js +6 -6
- package/lib/List/ListItem.js +28 -33
- package/lib/List/index.js +15 -0
- package/lib/Modal/Modal.js +10 -5
- package/lib/Notification/Notification.js +21 -5
- package/lib/Pagination/PageButton.js +16 -11
- package/lib/Pagination/Pagination.js +12 -7
- package/lib/Pagination/SideButton.js +12 -7
- package/lib/Pagination/usePagination.js +2 -2
- package/lib/Progress/Progress.js +10 -5
- package/lib/Progress/ProgressBar.js +21 -10
- package/lib/Progress/ProgressBarBackground.js +12 -8
- package/lib/Radio/Radio.js +14 -13
- package/lib/Radio/RadioButton.js +20 -9
- package/lib/Radio/RadioGroup.js +24 -13
- package/lib/RadioCard/RadioCard.js +14 -10
- package/lib/RadioCard/RadioCardGroup.js +13 -12
- package/lib/Search/Search.js +29 -18
- package/lib/Select/Picker.js +11 -6
- package/lib/Select/Picker.native.js +21 -6
- package/lib/Select/Select.js +46 -4
- package/lib/SideNav/Item.js +10 -5
- package/lib/SideNav/ItemsGroup.js +10 -5
- package/lib/SideNav/SideNav.js +11 -7
- package/lib/Skeleton/Skeleton.js +15 -15
- package/lib/Skeleton/skeletonWebAnimation.js +1 -1
- package/lib/Spacer/Spacer.js +19 -7
- package/lib/StackView/StackView.js +26 -7
- package/lib/StackView/StackWrap.js +24 -13
- package/lib/StackView/StackWrapBox.js +34 -8
- package/lib/StackView/StackWrapGap.js +16 -7
- package/lib/StackView/common.js +4 -2
- package/lib/StackView/getStackedContent.js +2 -2
- package/lib/StepTracker/StepTracker.js +10 -5
- package/lib/Tabs/Tabs.js +26 -19
- package/lib/Tabs/TabsItem.js +16 -12
- package/lib/Tags/Tags.js +27 -11
- package/lib/TextInput/TextArea.js +7 -5
- package/lib/TextInput/TextInput.js +12 -6
- package/lib/TextInput/TextInputBase.js +12 -8
- package/lib/ThemeProvider/ThemeProvider.js +14 -10
- package/lib/ThemeProvider/useSetTheme.js +6 -1
- package/lib/ThemeProvider/utils/styles.js +2 -2
- package/lib/ThemeProvider/utils/theme-tokens.js +39 -8
- package/lib/ToggleSwitch/ToggleSwitch.js +11 -6
- package/lib/Tooltip/Backdrop.js +10 -2
- package/lib/Tooltip/Tooltip.js +5 -4
- package/lib/Typography/Typography.js +40 -24
- package/lib/index.js +36 -1
- package/lib/utils/a11y/index.js +13 -0
- package/lib/utils/a11y/propTypes.js +61 -0
- package/lib/utils/a11y/propTypes.native.js +47 -0
- package/lib/utils/a11y/semantics.js +173 -0
- package/lib/utils/animation/useVerticalExpandAnimation.js +1 -1
- package/lib/utils/children.js +55 -8
- package/lib/utils/input.js +27 -17
- package/lib/utils/propTypes.js +40 -68
- package/lib/utils/useCopy.js +1 -1
- package/lib/utils/useHash.js +8 -4
- package/lib/utils/useSpacingScale.js +1 -3
- package/lib/utils/useUniqueId.js +1 -1
- package/package.json +14 -6
- package/release-context.json +4 -4
- package/src/A11yText/index.jsx +6 -4
- package/src/ActivityIndicator/Spinner.jsx +5 -3
- package/src/ActivityIndicator/Spinner.native.jsx +5 -3
- package/src/Box/Box.jsx +125 -39
- package/src/Button/Button.jsx +7 -4
- package/src/Button/ButtonBase.jsx +86 -77
- package/src/Button/ButtonGroup.jsx +81 -69
- package/src/Button/ButtonLink.jsx +18 -13
- package/src/Card/Card.jsx +2 -2
- package/src/Card/CardBase.jsx +6 -4
- package/src/Card/PressableCardBase.jsx +71 -64
- package/src/Checkbox/Checkbox.jsx +118 -108
- package/src/Checkbox/CheckboxGroup.jsx +72 -62
- package/src/Divider/Divider.jsx +7 -4
- package/src/ExpandCollapse/Accordion.jsx +3 -2
- package/src/ExpandCollapse/Control.jsx +40 -43
- package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
- package/src/ExpandCollapse/Panel.jsx +69 -63
- package/src/Feedback/Feedback.jsx +36 -33
- package/src/Fieldset/Fieldset.jsx +63 -56
- package/src/Fieldset/FieldsetContainer.jsx +14 -5
- package/src/Fieldset/FieldsetContainer.native.jsx +7 -4
- package/src/Fieldset/Legend.jsx +7 -2
- package/src/Fieldset/Legend.native.jsx +7 -2
- package/src/FlexGrid/Col/Col.jsx +139 -132
- package/src/FlexGrid/FlexGrid.jsx +79 -51
- package/src/FlexGrid/Row/Row.jsx +55 -48
- package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
- package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
- package/src/{Tabs → HorizontalScroll}/ScrollViewEnd.jsx +0 -0
- package/src/{Tabs → HorizontalScroll}/ScrollViewEnd.native.jsx +0 -0
- package/src/{Tabs → HorizontalScroll}/dictionary.js +0 -0
- package/src/HorizontalScroll/index.js +17 -0
- package/src/{Tabs → HorizontalScroll}/itemPositions.js +0 -0
- package/src/Icon/Icon.jsx +37 -35
- package/src/Icon/IconText.jsx +22 -17
- package/src/IconButton/IconButton.jsx +49 -42
- package/src/InputLabel/InputLabel.jsx +53 -38
- package/src/InputLabel/LabelContent.jsx +14 -6
- package/src/InputLabel/LabelContent.native.jsx +11 -2
- package/src/InputSupports/InputSupports.jsx +29 -34
- package/src/Link/ChevronLink.jsx +26 -16
- package/src/Link/InlinePressable.jsx +5 -3
- package/src/Link/InlinePressable.native.jsx +5 -3
- package/src/Link/Link.jsx +22 -16
- package/src/Link/LinkBase.jsx +67 -58
- package/src/Link/TextButton.jsx +30 -23
- package/src/List/List.jsx +6 -7
- package/src/List/ListItem.jsx +70 -90
- package/src/List/index.js +5 -0
- package/src/Modal/Modal.jsx +9 -4
- package/src/Notification/Notification.jsx +58 -43
- package/src/Pagination/PageButton.jsx +37 -34
- package/src/Pagination/Pagination.jsx +88 -92
- package/src/Pagination/SideButton.jsx +44 -41
- package/src/Progress/Progress.jsx +5 -4
- package/src/Progress/ProgressBar.jsx +42 -29
- package/src/Progress/ProgressBarBackground.jsx +5 -3
- package/src/Radio/Radio.jsx +85 -78
- package/src/Radio/RadioButton.jsx +54 -43
- package/src/Radio/RadioGroup.jsx +74 -63
- package/src/RadioCard/RadioCard.jsx +75 -68
- package/src/RadioCard/RadioCardGroup.jsx +82 -75
- package/src/Search/Search.jsx +127 -106
- package/src/Select/Picker.jsx +49 -42
- package/src/Select/Picker.native.jsx +56 -49
- package/src/Select/Select.jsx +115 -72
- package/src/SideNav/Item.jsx +53 -46
- package/src/SideNav/ItemsGroup.jsx +50 -43
- package/src/SideNav/SideNav.jsx +68 -60
- package/src/Skeleton/Skeleton.jsx +9 -13
- package/src/Spacer/Spacer.jsx +11 -4
- package/src/StackView/StackView.jsx +47 -23
- package/src/StackView/StackWrap.jsx +14 -12
- package/src/StackView/StackWrapBox.jsx +62 -28
- package/src/StackView/StackWrapGap.jsx +46 -24
- package/src/StackView/common.jsx +3 -2
- package/src/StepTracker/StepTracker.jsx +73 -62
- package/src/Tabs/Tabs.jsx +70 -62
- package/src/Tabs/TabsItem.jsx +111 -103
- package/src/Tags/Tags.jsx +114 -102
- package/src/TextInput/TextArea.jsx +5 -4
- package/src/TextInput/TextInput.jsx +5 -4
- package/src/TextInput/TextInputBase.jsx +84 -77
- package/src/ThemeProvider/ThemeProvider.jsx +11 -7
- package/src/ThemeProvider/useSetTheme.js +4 -0
- package/src/ThemeProvider/utils/theme-tokens.js +28 -0
- package/src/ToggleSwitch/ToggleSwitch.jsx +49 -50
- package/src/Tooltip/Tooltip.jsx +134 -130
- package/src/Typography/Typography.jsx +67 -44
- package/src/index.js +3 -1
- package/src/utils/a11y/index.js +1 -0
- package/src/utils/a11y/propTypes.js +61 -0
- package/src/utils/a11y/propTypes.native.js +39 -0
- package/src/utils/a11y/semantics.js +162 -0
- package/src/utils/children.jsx +60 -7
- package/src/utils/input.js +20 -17
- package/src/utils/propTypes.js +30 -76
- package/src/utils/useCopy.js +1 -1
- package/src/utils/useHash.js +8 -3
- package/stories/A11yText/A11yText.stories.jsx +3 -3
- package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +2 -2
- package/stories/Box/Box.stories.jsx +2 -2
- package/stories/Button/Button.stories.jsx +3 -3
- package/stories/Button/ButtonGroup.stories.jsx +2 -2
- package/stories/Button/ButtonLink.stories.jsx +2 -2
- package/stories/Card/Card.stories.jsx +2 -2
- package/stories/Checkbox/Checkbox.stories.jsx +2 -2
- package/stories/Divider/Divider.stories.jsx +2 -2
- package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +3 -3
- package/stories/Feedback/Feedback.stories.jsx +2 -2
- package/stories/FlexGrid/01 FlexGrid.stories.jsx +2 -2
- package/stories/FlexGrid/02 Row.stories.jsx +2 -2
- package/stories/FlexGrid/03 Col.stories.jsx +2 -2
- package/stories/Icon/Icon.stories.jsx +2 -2
- package/stories/IconButton/IconButton.stories.jsx +2 -2
- package/stories/InputLabel/InputLabel.stories.jsx +2 -2
- package/stories/Link/ChevronLink.stories.jsx +2 -2
- package/stories/Link/Link.stories.jsx +2 -2
- package/stories/Link/TextButton.stories.jsx +2 -2
- package/stories/List/List.stories.jsx +2 -2
- package/stories/Modal/Modal.stories.jsx +2 -2
- package/stories/Notification/Notification.stories.jsx +2 -2
- package/stories/Pagination/Pagination.stories.jsx +2 -2
- package/stories/Progress/Progress.stories.jsx +2 -2
- package/stories/Radio/Radio.stories.jsx +2 -2
- package/stories/RadioCard/RadioCard.stories.jsx +2 -2
- package/stories/Search/Search.stories.jsx +2 -2
- package/stories/Select/Select.stories.jsx +2 -2
- package/stories/SideNav/SideNav.stories.jsx +2 -2
- package/stories/SideNav/SideNavItem.stories.jsx +2 -2
- package/stories/SideNav/SideNavItemsGroup.stories.jsx +2 -2
- package/stories/Skeleton/Skeleton.stories.jsx +3 -3
- package/stories/Spacer/Spacer.stories.jsx +2 -2
- package/stories/StackView/StackView.stories.jsx +2 -2
- package/stories/StackView/StackWrap.stories.jsx +2 -2
- package/stories/StepTracker/StepTracker.stories.jsx +2 -2
- package/stories/Tabs/Tabs.stories.jsx +2 -2
- package/stories/Tags/Tags.stories.jsx +2 -2
- package/stories/TextInput/TextArea.stories.jsx +2 -2
- package/stories/TextInput/TextInput.stories.jsx +2 -2
- package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +2 -2
- package/stories/Tooltip/Tooltip.stories.jsx +2 -2
- package/stories/TooltipButton/TooltipButton.stories.jsx +2 -2
- package/stories/Typography/Typography.stories.jsx +2 -2
- package/stories/platform-supports.jsx +1 -1
- package/stories/supports.jsx +4 -5
- package/src/Tabs/HorizontalScroll.jsx +0 -165
- package/src/Tabs/TabsScrollButton.jsx +0 -100
package/src/Select/Select.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
import { View, Platform, StyleSheet } from 'react-native'
|
|
4
4
|
import PropTypes from 'prop-types'
|
|
@@ -147,100 +147,143 @@ const selectValidationIconContainerStyles = ({
|
|
|
147
147
|
* NOTE: this does not work on native platforms - the grouped items will be shown at the same level as the non-grouped items.
|
|
148
148
|
*
|
|
149
149
|
*/
|
|
150
|
-
const Select = (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
150
|
+
const Select = forwardRef(
|
|
151
|
+
(
|
|
152
|
+
{
|
|
153
|
+
value,
|
|
154
|
+
initialValue,
|
|
155
|
+
onChange,
|
|
156
|
+
children,
|
|
157
|
+
inactive,
|
|
158
|
+
readOnly,
|
|
159
|
+
placeholder,
|
|
160
|
+
validation,
|
|
161
|
+
tokens,
|
|
162
|
+
variant,
|
|
163
|
+
testID,
|
|
164
|
+
...rest
|
|
165
|
+
},
|
|
166
|
+
ref
|
|
167
|
+
) => {
|
|
168
|
+
const { currentValue, setValue } = useInputValue({
|
|
169
|
+
value,
|
|
170
|
+
initialValue,
|
|
171
|
+
onChange,
|
|
172
|
+
readOnly
|
|
173
|
+
})
|
|
170
174
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
const [isFocused, setIsFocused] = useState(false)
|
|
176
|
+
const handleFocus = () => setIsFocused(true)
|
|
177
|
+
const handleBlur = () => setIsFocused(false)
|
|
174
178
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
const [isHovered, setIsHovered] = useState(false)
|
|
180
|
+
const handleMouseOver = () => setIsHovered(true)
|
|
181
|
+
const handleMouseOut = () => setIsHovered(false)
|
|
178
182
|
|
|
179
|
-
|
|
183
|
+
const { props: supportsProps } = inputSupportsProps.select(rest)
|
|
180
184
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
const themeTokens = useThemeTokens('Select', tokens, variant, {
|
|
186
|
+
focus: isFocused,
|
|
187
|
+
hover: isHovered,
|
|
188
|
+
inactive,
|
|
189
|
+
validation
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
const { icon: IconComponent, validationIcon: ValidationIconComponent } = themeTokens
|
|
187
193
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
{children}
|
|
209
|
-
</Picker>
|
|
210
|
-
{ValidationIconComponent && (
|
|
211
|
-
<View
|
|
212
|
-
pointerEvents="none"
|
|
213
|
-
style={[staticStyles.iconContainer, selectValidationIconContainerStyles(themeTokens)]}
|
|
194
|
+
return (
|
|
195
|
+
<InputSupports {...supportsProps}>
|
|
196
|
+
{({ a11yProps, inputId }) => (
|
|
197
|
+
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
198
|
+
<Picker
|
|
199
|
+
ref={ref}
|
|
200
|
+
style={selectInputStyles(themeTokens, inactive)}
|
|
201
|
+
onFocus={handleFocus}
|
|
202
|
+
onBlur={handleBlur}
|
|
203
|
+
onMouseOver={handleMouseOver}
|
|
204
|
+
onMouseOut={handleMouseOut}
|
|
205
|
+
onChange={setValue}
|
|
206
|
+
value={currentValue}
|
|
207
|
+
inactive={inactive}
|
|
208
|
+
placeholder={
|
|
209
|
+
placeholder !== undefined ? { label: placeholder, value: '' } : undefined
|
|
210
|
+
}
|
|
211
|
+
{...a11yProps}
|
|
212
|
+
nativeID={inputId}
|
|
213
|
+
testID={testID}
|
|
214
214
|
>
|
|
215
|
-
|
|
216
|
-
</
|
|
217
|
-
|
|
218
|
-
{IconComponent &&
|
|
219
|
-
Platform.OS !== 'android' && ( // we can't hide the default caret of a native picker on android
|
|
215
|
+
{children}
|
|
216
|
+
</Picker>
|
|
217
|
+
{ValidationIconComponent && (
|
|
220
218
|
<View
|
|
221
219
|
pointerEvents="none"
|
|
222
|
-
style={[
|
|
220
|
+
style={[
|
|
221
|
+
staticStyles.iconContainer,
|
|
222
|
+
selectValidationIconContainerStyles(themeTokens)
|
|
223
|
+
]}
|
|
223
224
|
>
|
|
224
|
-
<
|
|
225
|
+
<ValidationIconComponent tokens={selectValidationIconTokens(themeTokens)} />
|
|
225
226
|
</View>
|
|
226
227
|
)}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
228
|
+
{IconComponent &&
|
|
229
|
+
Platform.OS !== 'android' && ( // we can't hide the default caret of a native picker on android
|
|
230
|
+
<View
|
|
231
|
+
pointerEvents="none"
|
|
232
|
+
style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
|
|
233
|
+
>
|
|
234
|
+
<IconComponent {...selectIconTokens(themeTokens)} />
|
|
235
|
+
</View>
|
|
236
|
+
)}
|
|
237
|
+
</View>
|
|
238
|
+
)}
|
|
239
|
+
</InputSupports>
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
Select.displayName = 'Select'
|
|
232
244
|
|
|
233
245
|
Select.propTypes = {
|
|
234
246
|
...inputSupportsProps.types,
|
|
247
|
+
/**
|
|
248
|
+
* Initial value for the uncontrolled version.
|
|
249
|
+
*/
|
|
235
250
|
initialValue: PropTypes.string,
|
|
251
|
+
/**
|
|
252
|
+
* Current value to be set as selected.
|
|
253
|
+
*/
|
|
236
254
|
value: PropTypes.string,
|
|
255
|
+
/**
|
|
256
|
+
* Callback to be called when the value changes.
|
|
257
|
+
*/
|
|
237
258
|
onChange: PropTypes.func,
|
|
259
|
+
/**
|
|
260
|
+
* An array of items or item groups to be used as options.
|
|
261
|
+
*/
|
|
238
262
|
children: componentPropType(['Item', 'Group']),
|
|
263
|
+
/**
|
|
264
|
+
* Whether the select is disabled.
|
|
265
|
+
*/
|
|
239
266
|
inactive: PropTypes.bool,
|
|
267
|
+
/**
|
|
268
|
+
* Whether the select is read-only.
|
|
269
|
+
*/
|
|
240
270
|
readOnly: PropTypes.bool,
|
|
271
|
+
/**
|
|
272
|
+
* A placeholder to provide instructions (such as "Please select...")
|
|
273
|
+
* as an unselectable option
|
|
274
|
+
*/
|
|
241
275
|
placeholder: PropTypes.string,
|
|
276
|
+
/**
|
|
277
|
+
* Select tokens.
|
|
278
|
+
*/
|
|
242
279
|
tokens: getTokensPropType('Select'),
|
|
280
|
+
/**
|
|
281
|
+
* Select variant.
|
|
282
|
+
*/
|
|
243
283
|
variant: variantProp.propType,
|
|
284
|
+
/**
|
|
285
|
+
* Dedicated ID for testing.
|
|
286
|
+
*/
|
|
244
287
|
testID: PropTypes.string
|
|
245
288
|
}
|
|
246
289
|
|
package/src/SideNav/Item.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import { Pressable } from 'react-native'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
|
|
@@ -37,54 +37,61 @@ function selectItemStyles({
|
|
|
37
37
|
|
|
38
38
|
This component can only be accessed as a name-spaced component: `SideNav.Item`.
|
|
39
39
|
*/
|
|
40
|
-
const Item = (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
const Item = forwardRef(
|
|
41
|
+
(
|
|
42
|
+
{
|
|
43
|
+
children,
|
|
44
|
+
itemId,
|
|
45
|
+
groupId,
|
|
46
|
+
onPress,
|
|
47
|
+
isActive = false,
|
|
48
|
+
isExpanded = false,
|
|
49
|
+
tokens,
|
|
50
|
+
variant,
|
|
51
|
+
href,
|
|
52
|
+
accessibilityRole = 'link',
|
|
53
|
+
testID,
|
|
54
|
+
...props
|
|
55
|
+
},
|
|
56
|
+
ref
|
|
57
|
+
) => {
|
|
58
|
+
const handlePress = () => onPress(itemId, groupId)
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
|
|
61
|
+
const linkPropSet = linkProps.select({
|
|
62
|
+
accessibilityRole,
|
|
63
|
+
href,
|
|
64
|
+
onPress: handlePress,
|
|
65
|
+
hrefAttrs,
|
|
66
|
+
...rest
|
|
67
|
+
})
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
const getTokens = useThemeTokensCallback('SideNavItem', tokens, variant)
|
|
70
|
+
const getAppearanceState = ({ hovered }) => ({
|
|
71
|
+
hover: hovered,
|
|
72
|
+
active: isActive,
|
|
73
|
+
expanded: isExpanded
|
|
74
|
+
})
|
|
75
|
+
const getPressableStyle = (pressableState) =>
|
|
76
|
+
selectItemStyles(getTokens(getAppearanceState(pressableState)))
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
return (
|
|
79
|
+
<Pressable
|
|
80
|
+
ref={ref}
|
|
81
|
+
style={getPressableStyle}
|
|
82
|
+
{...linkPropSet}
|
|
83
|
+
accessibilityState={{ selected: isActive }}
|
|
84
|
+
testID={testID}
|
|
85
|
+
>
|
|
86
|
+
{(pressableState) => {
|
|
87
|
+
const themeTokens = getTokens(getAppearanceState(pressableState))
|
|
88
|
+
return <ItemContent tokens={themeTokens}>{children}</ItemContent>
|
|
89
|
+
}}
|
|
90
|
+
</Pressable>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
Item.displayName = 'Item'
|
|
88
95
|
|
|
89
96
|
Item.propTypes = {
|
|
90
97
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
4
|
import ItemContent from './ItemContent'
|
|
@@ -16,52 +16,59 @@ import { useThemeTokensCallback } from '../ThemeProvider'
|
|
|
16
16
|
## Usage Criteria
|
|
17
17
|
- Use `SideNav.ItemsGroup` with large pages that have multiple sections
|
|
18
18
|
*/
|
|
19
|
-
const ItemsGroup = (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
const ItemsGroup = forwardRef(
|
|
20
|
+
(
|
|
21
|
+
{
|
|
22
|
+
children,
|
|
23
|
+
label,
|
|
24
|
+
openGroups,
|
|
25
|
+
groupId,
|
|
26
|
+
isActive = false,
|
|
27
|
+
variant,
|
|
28
|
+
tokens,
|
|
29
|
+
itemTokens,
|
|
30
|
+
onToggle
|
|
31
|
+
},
|
|
32
|
+
ref
|
|
33
|
+
) => {
|
|
34
|
+
// A SideNav control uses the same style and theme as SideNavItem, with a 'parent' variant,
|
|
35
|
+
// plus control-specific tokens from the SideNavItemsGroup theme (e.g. open/close icon, etc).
|
|
36
|
+
const getAppearance = (appearance) => ({ ...variant, ...appearance, active: isActive })
|
|
37
|
+
const getItemAppearance = (appearance) => ({ ...getAppearance(appearance), type: 'parent' })
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
const getGroupTokens = useThemeTokensCallback('SideNavItemsGroup', tokens, variant)
|
|
40
|
+
const getPanelTokens = (appearance) =>
|
|
41
|
+
selectTokens('ExpandCollapsePanel', getGroupTokens(getAppearance(appearance)))
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const getItemTokens = useThemeTokensCallback('SideNavItem', itemTokens, variant)
|
|
44
|
+
const getControlTokens = (appearance) =>
|
|
45
|
+
selectTokens('ExpandCollapseControl', {
|
|
46
|
+
...getItemTokens(getItemAppearance(appearance)), // main style from SideNavItem
|
|
47
|
+
...getGroupTokens(getAppearance(appearance)) // control-specific tokens like icon etc
|
|
48
|
+
})
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const controlContent = (controlState) => {
|
|
51
|
+
const currentItemTokens = getItemTokens(getItemAppearance(controlState))
|
|
52
|
+
return <ItemContent tokens={currentItemTokens}>{label}</ItemContent>
|
|
53
|
+
}
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
return (
|
|
56
|
+
<ExpandCollapse.Panel
|
|
57
|
+
ref={ref}
|
|
58
|
+
openIds={openGroups}
|
|
59
|
+
panelId={groupId}
|
|
60
|
+
onToggle={onToggle}
|
|
61
|
+
tokens={getPanelTokens}
|
|
62
|
+
controlTokens={getControlTokens}
|
|
63
|
+
control={controlContent}
|
|
64
|
+
accessibilityState={{ active: isActive }} // ExpandCollapse.Panel handles expanded state
|
|
65
|
+
>
|
|
66
|
+
{children}
|
|
67
|
+
</ExpandCollapse.Panel>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
ItemsGroup.displayName = 'ItemsGroup'
|
|
65
72
|
|
|
66
73
|
ItemsGroup.propTypes = {
|
|
67
74
|
/**
|
package/src/SideNav/SideNav.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
4
|
import ExpandCollapse from '../ExpandCollapse'
|
|
@@ -20,73 +20,81 @@ function selectBorderStyles(tokens) {
|
|
|
20
20
|
- Use in conjunction with a large amount of educational / informational content
|
|
21
21
|
- Allow the user to navigate between options frequently and efficiently
|
|
22
22
|
*/
|
|
23
|
-
const SideNav = (
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const SideNav = forwardRef(
|
|
24
|
+
({ children, variant = {}, tokens, accordion = true, itemTokens, groupTokens }, ref) => {
|
|
25
|
+
const themeTokens = useThemeTokens('SideNav', tokens, variant)
|
|
26
|
+
const [active, setActive] = useState({ groupId: undefined, itemId: undefined })
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const isItemActive = (itemId, groupId) => {
|
|
32
|
-
return active.groupId === groupId && active.itemId === itemId
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<ExpandCollapse maxOpen={accordion ? 1 : null} style={selectBorderStyles(themeTokens)}>
|
|
37
|
-
{({ openIds, onToggle }) => {
|
|
38
|
-
const renderItem = (item, index, groupId) => {
|
|
39
|
-
const { itemId = `item-${index}`, onPress } = item.props
|
|
40
|
-
const handlePress = (...args) => {
|
|
41
|
-
onItemPress(...args)
|
|
42
|
-
if (onPress) onPress(...args)
|
|
43
|
-
}
|
|
44
|
-
return (
|
|
45
|
-
<Item
|
|
46
|
-
{...item.props}
|
|
47
|
-
key={itemId}
|
|
48
|
-
itemId={itemId}
|
|
49
|
-
groupId={groupId}
|
|
50
|
-
variant={groupId ? { ...variant, type: 'child' } : variant}
|
|
51
|
-
tokens={itemTokens}
|
|
52
|
-
isActive={isItemActive(itemId, groupId)}
|
|
53
|
-
onPress={handlePress}
|
|
54
|
-
/>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
28
|
+
const onItemPress = (itemId, groupId) => {
|
|
29
|
+
setActive({ itemId, groupId })
|
|
30
|
+
}
|
|
57
31
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
const isItemActive = (itemId, groupId) => {
|
|
33
|
+
return active.groupId === groupId && active.itemId === itemId
|
|
34
|
+
}
|
|
61
35
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
36
|
+
return (
|
|
37
|
+
<ExpandCollapse
|
|
38
|
+
ref={ref}
|
|
39
|
+
maxOpen={accordion ? 1 : null}
|
|
40
|
+
style={selectBorderStyles(themeTokens)}
|
|
41
|
+
>
|
|
42
|
+
{({ openIds, onToggle }) => {
|
|
43
|
+
const renderItem = (item, index, groupId) => {
|
|
44
|
+
const { itemId = `item-${index}`, onPress } = item.props
|
|
45
|
+
const handlePress = (...args) => {
|
|
46
|
+
onItemPress(...args)
|
|
47
|
+
if (onPress) onPress(...args)
|
|
48
|
+
}
|
|
65
49
|
return (
|
|
66
|
-
<
|
|
67
|
-
{...
|
|
68
|
-
key={
|
|
50
|
+
<Item
|
|
51
|
+
{...item.props}
|
|
52
|
+
key={itemId}
|
|
53
|
+
itemId={itemId}
|
|
69
54
|
groupId={groupId}
|
|
70
|
-
variant={variant}
|
|
71
|
-
tokens={
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
onToggle={() => onToggle(groupId)}
|
|
76
|
-
>
|
|
77
|
-
{React.Children.map(child.props.children, (item, itemIndex) =>
|
|
78
|
-
renderItem(item, itemIndex, groupId)
|
|
79
|
-
)}
|
|
80
|
-
</ItemsGroup>
|
|
55
|
+
variant={groupId ? { ...variant, type: 'child' } : variant}
|
|
56
|
+
tokens={itemTokens}
|
|
57
|
+
isActive={isItemActive(itemId, groupId)}
|
|
58
|
+
onPress={handlePress}
|
|
59
|
+
/>
|
|
81
60
|
)
|
|
82
61
|
}
|
|
83
62
|
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
63
|
+
return React.Children.map(children, (child, index) => {
|
|
64
|
+
// iterate over children and identify them internally to later reference expanded groups and active items
|
|
65
|
+
if (child.type === Item) return renderItem(child, index)
|
|
66
|
+
|
|
67
|
+
if (child.type === ItemsGroup) {
|
|
68
|
+
const { groupId = `group-${index}` } = child.props
|
|
69
|
+
const isGroupActive = active.itemId !== undefined && active.groupId === groupId
|
|
70
|
+
const handleToggle = (event) => onToggle(groupId, event)
|
|
71
|
+
return (
|
|
72
|
+
<ItemsGroup
|
|
73
|
+
{...child.props}
|
|
74
|
+
key={groupId}
|
|
75
|
+
groupId={groupId}
|
|
76
|
+
variant={variant}
|
|
77
|
+
tokens={groupTokens}
|
|
78
|
+
itemTokens={itemTokens}
|
|
79
|
+
openGroups={openIds}
|
|
80
|
+
isActive={isGroupActive}
|
|
81
|
+
onToggle={handleToggle}
|
|
82
|
+
>
|
|
83
|
+
{React.Children.map(child.props.children, (item, itemIndex) =>
|
|
84
|
+
renderItem(item, itemIndex, groupId)
|
|
85
|
+
)}
|
|
86
|
+
</ItemsGroup>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return null
|
|
91
|
+
})
|
|
92
|
+
}}
|
|
93
|
+
</ExpandCollapse>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
SideNav.displayName = 'SideNav'
|
|
90
98
|
|
|
91
99
|
SideNav.propTypes = {
|
|
92
100
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import { Animated, Platform } from 'react-native'
|
|
3
3
|
import propTypes from 'prop-types'
|
|
4
4
|
import StackView from '../StackView'
|
|
@@ -27,7 +27,7 @@ const selectSquareStyles = ({ radius }) => ({
|
|
|
27
27
|
borderRadius: radius
|
|
28
28
|
})
|
|
29
29
|
|
|
30
|
-
const Skeleton = ({ tokens, variant, size, characters, lines, shape = 'line' }) => {
|
|
30
|
+
const Skeleton = forwardRef(({ tokens, variant, size, characters, lines, shape = 'line' }, ref) => {
|
|
31
31
|
const themeTokens = useThemeTokens('Skeleton', tokens, variant)
|
|
32
32
|
const skeletonHeight = useSpacingScale(size || themeTokens.size)
|
|
33
33
|
const nativeAnimation = useSkeletonNativeAnimation()
|
|
@@ -74,17 +74,13 @@ const Skeleton = ({ tokens, variant, size, characters, lines, shape = 'line' })
|
|
|
74
74
|
/>
|
|
75
75
|
)
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return renderSkeleton()
|
|
87
|
-
}
|
|
77
|
+
return (
|
|
78
|
+
<StackView space={themeTokens.spaceBetweenLines} ref={ref}>
|
|
79
|
+
{lines > 1 ? [...Array(lines)].map((_, index) => renderSkeleton(index)) : renderSkeleton()}
|
|
80
|
+
</StackView>
|
|
81
|
+
)
|
|
82
|
+
})
|
|
83
|
+
Skeleton.displayName = 'Skeleton'
|
|
88
84
|
|
|
89
85
|
Skeleton.propTypes = {
|
|
90
86
|
tokens: getTokensPropType('Skeleton'),
|
package/src/Spacer/Spacer.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { StyleSheet, View } from 'react-native'
|
|
4
4
|
|
|
@@ -54,11 +54,14 @@ const selectSizeStyle = (size, direction) => ({
|
|
|
54
54
|
* Spacer has no content and is ignored by tools such as screen readers. Use `Divider` for
|
|
55
55
|
* separations between elements that may be treated as semantically meaningful on web.
|
|
56
56
|
*/
|
|
57
|
-
const Spacer = ({ space = 1, direction = 'column', testID }) => {
|
|
57
|
+
const Spacer = forwardRef(({ space = 1, direction = 'column', testID, dataSet }, ref) => {
|
|
58
58
|
const size = useSpacingScale(space)
|
|
59
59
|
const sizeStyle = selectSizeStyle(size, direction)
|
|
60
|
-
return
|
|
61
|
-
}
|
|
60
|
+
return (
|
|
61
|
+
<View ref={ref} testID={testID} style={[staticStyles.stretch, sizeStyle]} dataSet={dataSet} />
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
Spacer.displayName = 'Spacer'
|
|
62
65
|
|
|
63
66
|
Spacer.propTypes = {
|
|
64
67
|
/**
|
|
@@ -74,6 +77,10 @@ Spacer.propTypes = {
|
|
|
74
77
|
* - `'row'` applies space horizontally; has a fixed width and not height.
|
|
75
78
|
*/
|
|
76
79
|
direction: PropTypes.oneOf(['column', 'row']),
|
|
80
|
+
/**
|
|
81
|
+
* @ignore
|
|
82
|
+
*/
|
|
83
|
+
dataSet: PropTypes.object,
|
|
77
84
|
/**
|
|
78
85
|
* @ignore
|
|
79
86
|
* In tests, the only way to select Spacers is with testID prop and getByTestId, since they have no content,
|