@telus-uds/components-base 0.0.2-prerelease.4 → 0.0.2-prerelease.8
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/.ultra.cache.json +1 -0
- package/CHANGELOG.md +76 -0
- package/__fixtures__/Accessible.js +33 -0
- package/__fixtures__/Accessible.native.js +32 -0
- package/__fixtures__/testTheme.js +940 -54
- package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
- package/__tests__/Button/ButtonBase.test.jsx +3 -32
- package/__tests__/Button/ButtonGroup.test.jsx +2 -2
- package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
- package/__tests__/Checkbox/CheckboxGroup.test.jsx +247 -0
- package/__tests__/Divider/Divider.test.jsx +26 -5
- package/__tests__/Feedback/Feedback.test.jsx +42 -0
- package/__tests__/Icon/Icon.test.jsx +3 -3
- package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
- package/__tests__/List/List.test.jsx +60 -0
- package/__tests__/Modal/Modal.test.jsx +47 -0
- package/__tests__/Notification/Notification.test.jsx +20 -0
- package/__tests__/Pagination/Pagination.test.jsx +2 -2
- package/__tests__/Progress/Progress.test.jsx +79 -0
- package/__tests__/Radio/Radio.test.jsx +87 -0
- package/__tests__/Radio/RadioGroup.test.jsx +221 -0
- package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
- package/__tests__/RadioCard/RadioCardGroup.test.jsx +247 -0
- package/__tests__/Search/Search.test.jsx +72 -0
- package/__tests__/Select/Select.test.jsx +93 -0
- package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
- package/__tests__/Spacer/Spacer.test.jsx +63 -0
- package/__tests__/StackView/StackView.test.jsx +216 -0
- package/__tests__/StackView/StackWrap.test.jsx +47 -0
- package/__tests__/StackView/getStackedContent.test.jsx +295 -0
- package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
- package/__tests__/Tabs/Tabs.test.jsx +200 -0
- package/__tests__/Tags/Tags.test.jsx +328 -0
- package/__tests__/TextInput/TextArea.test.jsx +34 -0
- package/__tests__/TextInput/TextInputBase.test.jsx +120 -0
- package/__tests__/Tooltip/Tooltip.test.jsx +65 -0
- package/__tests__/Tooltip/getTooltipPosition.test.js +79 -0
- package/__tests__/utils/input.test.js +58 -0
- package/__tests__/utils/useCopy.test.js +42 -0
- package/__tests__/utils/useResponsiveProp.test.jsx +202 -0
- package/__tests__/utils/{spacing.test.jsx → useSpacingScale.test.jsx} +1 -1
- package/__tests__/utils/useUniqueId.test.js +31 -0
- package/babel.config.js +20 -0
- package/jest.config.js +8 -2
- package/lib/A11yInfoProvider/index.js +54 -26
- package/lib/A11yText/index.js +37 -14
- package/lib/ActivityIndicator/Spinner.js +78 -0
- package/lib/ActivityIndicator/Spinner.native.js +121 -87
- package/lib/ActivityIndicator/index.js +28 -12
- package/lib/ActivityIndicator/shared.js +27 -12
- package/lib/BaseProvider/index.js +34 -11
- package/lib/Box/Box.js +56 -28
- package/lib/Box/index.js +13 -2
- package/lib/Button/Button.js +38 -10
- package/lib/Button/ButtonBase.js +120 -109
- package/lib/Button/ButtonGroup.js +98 -99
- package/lib/Button/ButtonLink.js +41 -13
- package/lib/Button/index.js +31 -4
- package/lib/Button/propTypes.js +32 -9
- package/lib/Card/Card.js +36 -41
- package/lib/Card/CardBase.js +78 -0
- package/lib/Card/PressableCardBase.js +137 -0
- package/lib/Card/index.js +40 -2
- package/lib/Checkbox/Checkbox.js +344 -0
- package/lib/Checkbox/CheckboxGroup.js +231 -0
- package/lib/Checkbox/CheckboxInput.js +74 -0
- package/lib/Checkbox/CheckboxInput.native.js +14 -0
- package/lib/Checkbox/index.js +21 -0
- package/lib/Divider/Divider.js +81 -17
- package/lib/Divider/index.js +13 -2
- package/lib/ExpandCollapse/Accordion.js +20 -7
- package/lib/ExpandCollapse/Control.js +50 -27
- package/lib/ExpandCollapse/ExpandCollapse.js +41 -24
- package/lib/ExpandCollapse/Panel.js +75 -37
- package/lib/ExpandCollapse/index.js +25 -7
- package/lib/Feedback/Feedback.js +161 -0
- package/lib/Feedback/index.js +13 -0
- package/lib/Fieldset/Fieldset.js +160 -0
- package/lib/Fieldset/FieldsetContainer.js +41 -0
- package/lib/Fieldset/FieldsetContainer.native.js +33 -0
- package/lib/Fieldset/Legend.js +33 -0
- package/lib/Fieldset/Legend.native.js +43 -0
- package/lib/Fieldset/cssReset.js +21 -0
- package/lib/Fieldset/index.js +13 -0
- package/lib/FlexGrid/Col/Col.js +67 -38
- package/lib/FlexGrid/Col/index.js +13 -2
- package/lib/FlexGrid/FlexGrid.js +70 -45
- package/lib/FlexGrid/Row/Row.js +48 -27
- package/lib/FlexGrid/Row/index.js +13 -2
- package/lib/FlexGrid/helpers/index.js +9 -1
- package/lib/FlexGrid/index.js +13 -2
- package/lib/FlexGrid/providers/GutterContext.js +15 -3
- package/lib/Icon/Icon.js +52 -47
- package/lib/Icon/IconText.js +100 -0
- package/lib/Icon/index.js +31 -3
- package/lib/InputLabel/InputLabel.js +122 -0
- package/lib/InputLabel/LabelContent.js +31 -0
- package/lib/InputLabel/LabelContent.native.js +16 -0
- package/lib/InputLabel/index.js +13 -0
- package/lib/InputSupports/InputSupports.js +104 -0
- package/lib/InputSupports/index.js +13 -0
- package/lib/InputSupports/propTypes.js +66 -0
- package/lib/InputSupports/useInputSupports.js +41 -0
- package/lib/Link/ChevronLink.js +57 -15
- package/lib/Link/InlinePressable.js +50 -0
- package/lib/Link/InlinePressable.native.js +101 -0
- package/lib/Link/Link.js +30 -13
- package/lib/Link/LinkBase.js +121 -146
- package/lib/Link/TextButton.js +47 -17
- package/lib/Link/index.js +39 -4
- package/lib/List/List.js +80 -0
- package/lib/List/ListItem.js +237 -0
- package/lib/List/index.js +13 -0
- package/lib/Modal/Modal.js +226 -0
- package/lib/Modal/dictionary.js +16 -0
- package/lib/Modal/index.js +13 -0
- package/lib/Notification/Notification.js +200 -0
- package/lib/Notification/dictionary.js +15 -0
- package/lib/Notification/index.js +13 -0
- package/lib/Pagination/PageButton.js +45 -46
- package/lib/Pagination/Pagination.js +70 -40
- package/lib/Pagination/SideButton.js +74 -58
- package/lib/Pagination/dictionary.js +9 -2
- package/lib/Pagination/index.js +13 -2
- package/lib/Pagination/usePagination.js +12 -2
- package/lib/Progress/Progress.js +99 -0
- package/lib/Progress/ProgressBar.js +146 -0
- package/lib/Progress/ProgressBarBackground.js +57 -0
- package/lib/Progress/index.js +16 -0
- package/lib/Radio/Radio.js +292 -0
- package/lib/Radio/RadioButton.js +141 -0
- package/lib/Radio/RadioGroup.js +233 -0
- package/lib/Radio/RadioInput.js +76 -0
- package/lib/Radio/RadioInput.native.js +14 -0
- package/lib/Radio/index.js +21 -0
- package/lib/RadioCard/RadioCard.js +240 -0
- package/lib/RadioCard/RadioCardGroup.js +251 -0
- package/lib/RadioCard/index.js +21 -0
- package/lib/Search/Search.js +243 -0
- package/lib/Search/dictionary.js +19 -0
- package/lib/Search/index.js +13 -0
- package/lib/Select/Group.js +33 -0
- package/lib/Select/Group.native.js +25 -0
- package/lib/Select/Item.js +29 -0
- package/lib/Select/Item.native.js +19 -0
- package/lib/Select/Picker.js +79 -0
- package/lib/Select/Picker.native.js +115 -0
- package/lib/Select/Select.js +300 -0
- package/lib/Select/index.js +19 -0
- package/lib/SideNav/Item.js +54 -33
- package/lib/SideNav/ItemContent.js +41 -15
- package/lib/SideNav/ItemsGroup.js +46 -27
- package/lib/SideNav/SideNav.js +92 -69
- package/lib/SideNav/index.js +15 -1
- package/lib/Skeleton/Skeleton.js +137 -0
- package/lib/Skeleton/index.js +13 -0
- package/lib/Skeleton/skeleton.constant.js +12 -0
- package/lib/Skeleton/skeletonWebAnimation.js +27 -0
- package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
- package/lib/Spacer/Spacer.js +117 -0
- package/lib/Spacer/index.js +13 -0
- package/lib/StackView/StackView.js +129 -0
- package/lib/StackView/StackWrap.js +55 -0
- package/lib/StackView/StackWrap.native.js +14 -0
- package/lib/StackView/StackWrapBox.js +112 -0
- package/lib/StackView/StackWrapGap.js +71 -0
- package/lib/StackView/common.js +45 -0
- package/lib/StackView/getStackedContent.js +141 -0
- package/lib/StackView/index.js +29 -0
- package/lib/StepTracker/Step.js +245 -0
- package/lib/StepTracker/StepTracker.js +197 -0
- package/lib/StepTracker/dictionary.js +17 -0
- package/lib/StepTracker/index.js +13 -0
- package/lib/Tabs/HorizontalScroll.js +199 -0
- package/lib/Tabs/ScrollViewEnd.js +66 -0
- package/lib/Tabs/ScrollViewEnd.native.js +41 -0
- package/lib/Tabs/Tabs.js +117 -0
- package/lib/Tabs/TabsItem.js +234 -0
- package/lib/Tabs/TabsScrollButton.js +121 -0
- package/lib/Tabs/dictionary.js +18 -0
- package/lib/Tabs/index.js +13 -0
- package/lib/Tabs/itemPositions.js +128 -0
- package/lib/Tags/Tags.js +250 -0
- package/lib/Tags/index.js +13 -0
- package/lib/TextInput/TextArea.js +109 -0
- package/lib/TextInput/TextInput.js +75 -0
- package/lib/TextInput/TextInputBase.js +252 -0
- package/lib/TextInput/index.js +23 -0
- package/lib/TextInput/propTypes.js +42 -0
- package/lib/ThemeProvider/ThemeProvider.js +38 -14
- package/lib/ThemeProvider/index.js +61 -6
- package/lib/ThemeProvider/useSetTheme.js +14 -5
- package/lib/ThemeProvider/useTheme.js +13 -4
- package/lib/ThemeProvider/useThemeTokens.js +86 -19
- package/lib/ThemeProvider/utils/index.js +31 -2
- package/lib/ThemeProvider/utils/styles.js +52 -16
- package/lib/ThemeProvider/utils/theme-tokens.js +94 -16
- package/lib/ToggleSwitch/ToggleSwitch.js +76 -52
- package/lib/ToggleSwitch/index.js +13 -2
- package/lib/Tooltip/Backdrop.js +56 -0
- package/lib/Tooltip/Backdrop.native.js +59 -0
- package/lib/Tooltip/Tooltip.js +357 -0
- package/lib/Tooltip/dictionary.js +15 -0
- package/lib/Tooltip/getTooltipPosition.js +172 -0
- package/lib/Tooltip/index.js +13 -0
- package/lib/TooltipButton/TooltipButton.js +83 -0
- package/lib/TooltipButton/index.js +13 -0
- package/lib/Typography/Typography.js +58 -47
- package/lib/Typography/index.js +13 -2
- package/lib/ViewportProvider/ViewportProvider.js +46 -0
- package/lib/ViewportProvider/index.js +22 -38
- package/lib/ViewportProvider/useViewport.js +15 -0
- package/lib/ViewportProvider/useViewportListener.js +57 -0
- package/lib/index.js +509 -19
- package/lib/utils/a11y/index.js +18 -0
- package/lib/utils/a11y/textSize.js +49 -0
- package/lib/utils/animation/index.js +15 -2
- package/lib/utils/animation/useVerticalExpandAnimation.js +28 -11
- package/lib/utils/children.js +87 -0
- package/lib/utils/index.js +163 -4
- package/lib/utils/info/index.js +19 -0
- package/lib/utils/info/platform/index.js +23 -0
- package/lib/utils/info/platform/platform.android.js +8 -0
- package/lib/utils/info/platform/platform.ios.js +8 -0
- package/lib/utils/info/platform/platform.js +8 -0
- package/lib/utils/info/platform/platform.native.js +11 -0
- package/lib/utils/info/versions.js +16 -0
- package/lib/utils/input.js +54 -34
- package/lib/utils/pressability.js +120 -0
- package/lib/utils/propTypes.js +269 -108
- package/lib/utils/useCopy.js +51 -0
- package/lib/utils/useHash.js +48 -0
- package/lib/utils/useHash.native.js +15 -0
- package/lib/utils/useResponsiveProp.js +59 -0
- package/lib/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +45 -12
- package/lib/utils/useUniqueId.js +21 -0
- package/package.json +11 -8
- package/release-context.json +4 -4
- package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +0 -0
- package/src/Box/Box.jsx +13 -4
- package/src/Button/Button.jsx +9 -5
- package/src/Button/ButtonBase.jsx +74 -86
- package/src/Button/ButtonGroup.jsx +24 -41
- package/src/Button/ButtonLink.jsx +14 -4
- package/src/Button/propTypes.js +12 -2
- package/src/Card/Card.jsx +4 -30
- package/src/Card/CardBase.jsx +57 -0
- package/src/Card/PressableCardBase.jsx +112 -0
- package/src/Card/index.js +3 -0
- package/src/Checkbox/Checkbox.jsx +274 -0
- package/src/Checkbox/CheckboxGroup.jsx +196 -0
- package/src/Checkbox/CheckboxInput.jsx +55 -0
- package/src/Checkbox/CheckboxInput.native.jsx +6 -0
- package/src/Checkbox/index.js +5 -0
- package/src/Divider/Divider.jsx +38 -3
- package/src/ExpandCollapse/Control.jsx +1 -1
- package/src/Feedback/Feedback.jsx +108 -0
- package/src/Feedback/index.js +3 -0
- package/src/Fieldset/Fieldset.jsx +129 -0
- package/src/Fieldset/FieldsetContainer.jsx +22 -0
- package/src/Fieldset/FieldsetContainer.native.jsx +16 -0
- package/src/Fieldset/Legend.jsx +16 -0
- package/src/Fieldset/Legend.native.jsx +22 -0
- package/src/Fieldset/cssReset.js +14 -0
- package/src/Fieldset/index.js +3 -0
- package/src/Icon/Icon.jsx +23 -27
- package/src/Icon/IconText.jsx +63 -0
- package/src/Icon/index.js +3 -2
- package/src/InputLabel/InputLabel.jsx +106 -0
- package/src/InputLabel/LabelContent.jsx +13 -0
- package/src/InputLabel/LabelContent.native.jsx +6 -0
- package/src/InputLabel/index.js +3 -0
- package/src/InputSupports/InputSupports.jsx +75 -0
- package/src/InputSupports/index.js +3 -0
- package/src/InputSupports/propTypes.js +44 -0
- package/src/InputSupports/useInputSupports.js +30 -0
- package/src/Link/ChevronLink.jsx +28 -7
- package/src/Link/InlinePressable.jsx +37 -0
- package/src/Link/InlinePressable.native.jsx +73 -0
- package/src/Link/Link.jsx +17 -13
- package/src/Link/LinkBase.jsx +71 -146
- package/src/Link/TextButton.jsx +25 -11
- package/src/Link/index.js +2 -1
- package/src/List/List.jsx +47 -0
- package/src/List/ListItem.jsx +187 -0
- package/src/List/index.js +3 -0
- package/src/Modal/Modal.jsx +185 -0
- package/src/Modal/dictionary.js +9 -0
- package/src/Modal/index.js +3 -0
- package/src/Notification/Notification.jsx +149 -0
- package/src/Notification/dictionary.js +8 -0
- package/src/Notification/index.js +3 -0
- package/src/Pagination/PageButton.jsx +3 -17
- package/src/Pagination/SideButton.jsx +27 -38
- package/src/Progress/Progress.jsx +77 -0
- package/src/Progress/ProgressBar.jsx +110 -0
- package/src/Progress/ProgressBarBackground.jsx +34 -0
- package/src/Progress/index.js +6 -0
- package/src/Radio/Radio.jsx +233 -0
- package/src/Radio/RadioButton.jsx +131 -0
- package/src/Radio/RadioGroup.jsx +198 -0
- package/src/Radio/RadioInput.jsx +57 -0
- package/src/Radio/RadioInput.native.jsx +6 -0
- package/src/Radio/index.js +5 -0
- package/src/RadioCard/RadioCard.jsx +191 -0
- package/src/RadioCard/RadioCardGroup.jsx +211 -0
- package/src/RadioCard/index.js +5 -0
- package/src/Search/Search.jsx +204 -0
- package/src/Search/dictionary.js +12 -0
- package/src/Search/index.js +3 -0
- package/src/Select/Group.jsx +15 -0
- package/src/Select/Group.native.jsx +14 -0
- package/src/Select/Item.jsx +11 -0
- package/src/Select/Item.native.jsx +10 -0
- package/src/Select/Picker.jsx +67 -0
- package/src/Select/Picker.native.jsx +95 -0
- package/src/Select/Select.jsx +255 -0
- package/src/Select/index.js +8 -0
- package/src/SideNav/Item.jsx +2 -2
- package/src/Skeleton/Skeleton.jsx +98 -0
- package/src/Skeleton/index.js +3 -0
- package/src/Skeleton/skeleton.constant.js +3 -0
- package/src/Skeleton/skeletonWebAnimation.js +13 -0
- package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
- package/src/Spacer/Spacer.jsx +91 -0
- package/src/Spacer/index.js +3 -0
- package/src/StackView/StackView.jsx +111 -0
- package/src/StackView/StackWrap.jsx +41 -0
- package/src/StackView/StackWrap.native.jsx +4 -0
- package/src/StackView/StackWrapBox.jsx +94 -0
- package/src/StackView/StackWrapGap.jsx +49 -0
- package/src/StackView/common.jsx +28 -0
- package/src/StackView/getStackedContent.jsx +112 -0
- package/src/StackView/index.js +6 -0
- package/src/StepTracker/Step.jsx +202 -0
- package/src/StepTracker/StepTracker.jsx +163 -0
- package/src/StepTracker/dictionary.js +10 -0
- package/src/StepTracker/index.js +3 -0
- package/src/Tabs/HorizontalScroll.jsx +165 -0
- package/src/Tabs/ScrollViewEnd.jsx +53 -0
- package/src/Tabs/ScrollViewEnd.native.jsx +24 -0
- package/src/Tabs/Tabs.jsx +89 -0
- package/src/Tabs/TabsItem.jsx +204 -0
- package/src/Tabs/TabsScrollButton.jsx +100 -0
- package/src/Tabs/dictionary.js +11 -0
- package/src/Tabs/index.js +3 -0
- package/src/Tabs/itemPositions.js +101 -0
- package/src/Tags/Tags.jsx +207 -0
- package/src/Tags/index.js +3 -0
- package/src/TextInput/TextArea.jsx +78 -0
- package/src/TextInput/TextInput.jsx +52 -0
- package/src/TextInput/TextInputBase.jsx +210 -0
- package/src/TextInput/index.js +4 -0
- package/src/TextInput/propTypes.js +29 -0
- package/src/ThemeProvider/useThemeTokens.js +56 -5
- package/src/ThemeProvider/utils/styles.js +18 -5
- package/src/ThemeProvider/utils/theme-tokens.js +46 -5
- package/src/ToggleSwitch/ToggleSwitch.jsx +3 -4
- package/src/Tooltip/Backdrop.jsx +60 -0
- package/src/Tooltip/Backdrop.native.jsx +33 -0
- package/src/Tooltip/Tooltip.jsx +294 -0
- package/src/Tooltip/dictionary.js +8 -0
- package/src/Tooltip/getTooltipPosition.js +161 -0
- package/src/Tooltip/index.js +3 -0
- package/src/TooltipButton/TooltipButton.jsx +49 -0
- package/src/TooltipButton/index.js +3 -0
- package/src/Typography/Typography.jsx +10 -24
- package/src/ViewportProvider/ViewportProvider.jsx +21 -0
- package/src/ViewportProvider/index.jsx +2 -41
- package/src/ViewportProvider/useViewport.js +5 -0
- package/src/ViewportProvider/useViewportListener.js +43 -0
- package/src/index.js +34 -2
- package/src/utils/a11y/index.js +1 -0
- package/src/utils/a11y/textSize.js +30 -0
- package/src/utils/children.jsx +66 -0
- package/src/utils/index.js +11 -1
- package/src/utils/info/index.js +8 -0
- package/src/utils/info/platform/index.js +11 -0
- package/src/utils/info/platform/platform.android.js +1 -0
- package/src/utils/info/platform/platform.ios.js +1 -0
- package/src/utils/info/platform/platform.js +1 -0
- package/src/utils/info/platform/platform.native.js +4 -0
- package/src/utils/info/versions.js +6 -0
- package/src/utils/input.js +22 -13
- package/src/utils/pressability.js +96 -0
- package/src/utils/propTypes.js +195 -47
- package/src/utils/useCopy.js +39 -0
- package/src/utils/useHash.js +34 -0
- package/src/utils/useHash.native.js +6 -0
- package/src/utils/useResponsiveProp.js +50 -0
- package/src/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +25 -10
- package/src/utils/useUniqueId.js +14 -0
- package/stories/A11yText/A11yText.stories.jsx +15 -13
- package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +11 -2
- package/stories/Box/Box.stories.jsx +29 -2
- package/stories/Button/Button.stories.jsx +21 -20
- package/stories/Button/ButtonGroup.stories.jsx +2 -1
- package/stories/Button/ButtonLink.stories.jsx +6 -4
- package/stories/Card/Card.stories.jsx +13 -1
- package/stories/Checkbox/Checkbox.stories.jsx +94 -0
- package/stories/Divider/Divider.stories.jsx +26 -2
- package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +74 -79
- package/stories/Feedback/Feedback.stories.jsx +96 -0
- package/stories/FlexGrid/01 FlexGrid.stories.jsx +20 -7
- package/stories/Icon/Icon.stories.jsx +15 -6
- package/stories/InputLabel/InputLabel.stories.jsx +42 -0
- package/stories/Link/ChevronLink.stories.jsx +20 -4
- package/stories/Link/Link.stories.jsx +39 -3
- package/stories/Link/TextButton.stories.jsx +24 -2
- package/stories/List/List.stories.jsx +117 -0
- package/stories/Modal/Modal.stories.jsx +29 -0
- package/stories/Notification/Notification.stories.jsx +82 -0
- package/stories/Pagination/Pagination.stories.jsx +28 -14
- package/stories/Progress/Progress.stories.jsx +93 -0
- package/stories/Radio/Radio.stories.jsx +100 -0
- package/stories/RadioCard/RadioCard.stories.jsx +98 -0
- package/stories/Search/Search.stories.jsx +16 -0
- package/stories/Select/Select.stories.jsx +55 -0
- package/stories/SideNav/SideNav.stories.jsx +17 -2
- package/stories/Skeleton/Skeleton.stories.jsx +36 -0
- package/stories/Spacer/Spacer.stories.jsx +38 -0
- package/stories/StackView/StackView.stories.jsx +75 -0
- package/stories/StackView/StackWrap.stories.jsx +64 -0
- package/stories/StepTracker/StepTracker.stories.jsx +71 -0
- package/stories/Tabs/Tabs.stories.jsx +97 -0
- package/stories/Tags/Tags.stories.jsx +69 -0
- package/stories/TextInput/TextArea.stories.jsx +100 -0
- package/stories/TextInput/TextInput.stories.jsx +103 -0
- package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +16 -3
- package/stories/Tooltip/Tooltip.stories.jsx +81 -0
- package/stories/TooltipButton/TooltipButton.stories.jsx +11 -0
- package/stories/Typography/Typography.stories.jsx +12 -3
- package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
- package/stories/supports.jsx +110 -14
- package/__fixtures__/accessible.icon.svg +0 -6
- package/babel.config.json +0 -8
- package/lib/ActivityIndicator/Spinner.web.js +0 -55
- package/lib/Pagination/useCopy.js +0 -10
- package/lib/config/svgr-icons-web.js +0 -9
- package/lib/config/svgr-icons.js +0 -52
- package/lib/utils/spacing/index.js +0 -2
- package/lib/utils/spacing/utils.js +0 -32
- package/src/Pagination/useCopy.js +0 -7
- package/src/config/svgr-icons-web.js +0 -11
- package/src/config/svgr-icons.js +0 -46
- package/src/utils/spacing/index.js +0 -3
- package/src/utils/spacing/utils.js +0 -28
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { View, StyleSheet } from 'react-native'
|
|
3
|
+
|
|
4
|
+
import PropTypes from 'prop-types'
|
|
5
|
+
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider'
|
|
6
|
+
import { getTokensPropType, selectTokens, useSpacingScale, variantProp } from '../utils'
|
|
7
|
+
import TextInputBase from '../TextInput/TextInputBase'
|
|
8
|
+
import ButtonBase from '../Button/ButtonBase'
|
|
9
|
+
import StackView from '../StackView'
|
|
10
|
+
import useCopy from '../utils/useCopy'
|
|
11
|
+
import dictionary from './dictionary'
|
|
12
|
+
|
|
13
|
+
const selectInputTokens = ({ searchTokens, buttonTokens, buttonsGapSize }) => {
|
|
14
|
+
const { paddingRight: inputPaddingRight, clearButtonIcon, submitButtonIcon } = searchTokens
|
|
15
|
+
const { paddingLeft = 0, paddingRight = 0, iconSize = 0 } = buttonTokens
|
|
16
|
+
|
|
17
|
+
const buttonWidth = paddingLeft + paddingRight + iconSize
|
|
18
|
+
|
|
19
|
+
const paddingWithButtons =
|
|
20
|
+
inputPaddingRight +
|
|
21
|
+
(submitButtonIcon ? buttonWidth : 0) +
|
|
22
|
+
(clearButtonIcon ? buttonsGapSize + buttonWidth : 0)
|
|
23
|
+
|
|
24
|
+
return { ...selectTokens('TextInput', searchTokens), paddingRight: paddingWithButtons }
|
|
25
|
+
}
|
|
26
|
+
const selectButtonTokens = (tokens) => selectTokens('Button', tokens)
|
|
27
|
+
|
|
28
|
+
const selectIconsContainerStyle = ({ paddingRight }) => ({ paddingRight })
|
|
29
|
+
const selectIconTokens = ({ iconSize, iconColor }) => ({ color: iconColor, size: iconSize })
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The `Search` component is a combination of a `TextInput` and 2 different kinds of custom buttons.
|
|
33
|
+
* Use `Search` to feature autocomplete interactions.
|
|
34
|
+
*
|
|
35
|
+
* This component includes a clear button, which will appear as text is entered and pressing it will
|
|
36
|
+
* cause the input's internal state value to be set to an empty string.
|
|
37
|
+
*
|
|
38
|
+
* This component may only be used as uncontrolled, as the search value is managed within an internal state.
|
|
39
|
+
* You can use the `onChange` prop to react to value changes and the `onSubmit` prop to react on search submission.
|
|
40
|
+
*
|
|
41
|
+
* Use the following props to supply additional accessibility labels for the input - `accessibilityLabel`,
|
|
42
|
+
* clear button - `clearButtonAccessibilityLabel`, and submit button - `submitButtonAccessibilityLabel`.
|
|
43
|
+
*/
|
|
44
|
+
const Search = ({
|
|
45
|
+
initialValue = '',
|
|
46
|
+
placeholder = 'Search',
|
|
47
|
+
inactive,
|
|
48
|
+
onChange,
|
|
49
|
+
onSubmit,
|
|
50
|
+
onClear,
|
|
51
|
+
accessibilityLabel,
|
|
52
|
+
copy = 'en',
|
|
53
|
+
tokens,
|
|
54
|
+
variant
|
|
55
|
+
}) => {
|
|
56
|
+
const [value, setValue] = useState(initialValue)
|
|
57
|
+
const themeTokens = useThemeTokens('Search', tokens, variant)
|
|
58
|
+
const buttonTokens = useThemeTokens('SearchButton', tokens, variant)
|
|
59
|
+
|
|
60
|
+
const getThemeTokens = useThemeTokensCallback('Search', tokens, variant)
|
|
61
|
+
const getButtonTokens = useThemeTokensCallback('SearchButton', tokens, variant)
|
|
62
|
+
|
|
63
|
+
// TODO: support overriding the a11y props using a custom dictionary
|
|
64
|
+
const getCopy = useCopy({ dictionary, copy })
|
|
65
|
+
|
|
66
|
+
const {
|
|
67
|
+
placeholderColor,
|
|
68
|
+
buttonsGap,
|
|
69
|
+
clearButtonIcon: ClearButtonIcon,
|
|
70
|
+
submitButtonIcon: SubmitButtonIcon
|
|
71
|
+
} = themeTokens
|
|
72
|
+
|
|
73
|
+
// get the actual gap value for the current viewport
|
|
74
|
+
const buttonsGapSize = useSpacingScale(buttonsGap)
|
|
75
|
+
|
|
76
|
+
const handleSubmit = () => {
|
|
77
|
+
if (onSubmit !== undefined) {
|
|
78
|
+
onSubmit(value)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const handleChange = (currentValue) => {
|
|
83
|
+
setValue(currentValue)
|
|
84
|
+
|
|
85
|
+
if (onChange !== undefined) onChange(currentValue)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const handleClear = () => {
|
|
89
|
+
setValue('')
|
|
90
|
+
|
|
91
|
+
if (onClear !== undefined) onClear()
|
|
92
|
+
if (onChange !== undefined) onChange('')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const isEmpty = value === ''
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<View>
|
|
99
|
+
<TextInputBase
|
|
100
|
+
tokens={(appearances) =>
|
|
101
|
+
selectInputTokens({
|
|
102
|
+
searchTokens: getThemeTokens(appearances),
|
|
103
|
+
buttonTokens,
|
|
104
|
+
buttonsGapSize,
|
|
105
|
+
isEmpty
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
placeholder={placeholder}
|
|
109
|
+
placeholderTextColor={placeholderColor}
|
|
110
|
+
inactive={inactive}
|
|
111
|
+
enablesReturnKeyAutomatically
|
|
112
|
+
returnKeyType="search"
|
|
113
|
+
value={value}
|
|
114
|
+
onChange={handleChange}
|
|
115
|
+
onSubmitEditing={handleSubmit}
|
|
116
|
+
accessibilityLabel={accessibilityLabel || getCopy('accessibilityLabel')}
|
|
117
|
+
/>
|
|
118
|
+
<View style={[staticStyles.iconsContainer, selectIconsContainerStyle(themeTokens)]}>
|
|
119
|
+
<StackView direction="row" space={buttonsGap}>
|
|
120
|
+
{ClearButtonIcon && !isEmpty && (
|
|
121
|
+
<ButtonBase
|
|
122
|
+
onPress={handleClear}
|
|
123
|
+
inactive={inactive}
|
|
124
|
+
accessibilityRole="button"
|
|
125
|
+
accessibilityLabel={getCopy('clearButtonAccessibilityLabel')}
|
|
126
|
+
tokens={(appearances) => selectButtonTokens(getButtonTokens(appearances))}
|
|
127
|
+
>
|
|
128
|
+
{(buttonState) => (
|
|
129
|
+
<ClearButtonIcon tokens={selectIconTokens(getButtonTokens(buttonState))} />
|
|
130
|
+
)}
|
|
131
|
+
</ButtonBase>
|
|
132
|
+
)}
|
|
133
|
+
{SubmitButtonIcon && (
|
|
134
|
+
<ButtonBase
|
|
135
|
+
onPress={handleSubmit}
|
|
136
|
+
inactive={inactive}
|
|
137
|
+
accessibilityRole="button"
|
|
138
|
+
accessibilityLabel={getCopy('submitButtonAccessibilityLabel')}
|
|
139
|
+
tokens={(buttonState) =>
|
|
140
|
+
selectButtonTokens(getButtonTokens({ ...buttonState, priority: 'high' }))
|
|
141
|
+
}
|
|
142
|
+
>
|
|
143
|
+
{(buttonState) => (
|
|
144
|
+
<SubmitButtonIcon
|
|
145
|
+
tokens={selectIconTokens(getButtonTokens({ ...buttonState, priority: 'high' }))}
|
|
146
|
+
/>
|
|
147
|
+
)}
|
|
148
|
+
</ButtonBase>
|
|
149
|
+
)}
|
|
150
|
+
</StackView>
|
|
151
|
+
</View>
|
|
152
|
+
</View>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Search.propTypes = {
|
|
157
|
+
/**
|
|
158
|
+
* Use this to set the initial value of the search input.
|
|
159
|
+
* Updating `initialValue` will **not** update the actual value.
|
|
160
|
+
*/
|
|
161
|
+
initialValue: PropTypes.string,
|
|
162
|
+
/**
|
|
163
|
+
* Label rendered in the search input when it has no value.
|
|
164
|
+
*/
|
|
165
|
+
placeholder: PropTypes.string,
|
|
166
|
+
/**
|
|
167
|
+
* Disables all user interactions with the search input.
|
|
168
|
+
*/
|
|
169
|
+
inactive: PropTypes.bool,
|
|
170
|
+
/**
|
|
171
|
+
* Use to react upon search input's value changes.
|
|
172
|
+
* Will receive the searched value as an argument.
|
|
173
|
+
*/
|
|
174
|
+
onChange: PropTypes.func,
|
|
175
|
+
/**
|
|
176
|
+
* Triggered when the search input is submitted,
|
|
177
|
+
* either by pressing the submit button, "Enter" key on web,
|
|
178
|
+
* or "Search" key in a mobile keyboard.
|
|
179
|
+
*/
|
|
180
|
+
onSubmit: PropTypes.func,
|
|
181
|
+
/**
|
|
182
|
+
* Triggered when the clear button is pressed.
|
|
183
|
+
*/
|
|
184
|
+
onClear: PropTypes.func,
|
|
185
|
+
/**
|
|
186
|
+
* Use to provide an accessible label for the input (visually hidden).
|
|
187
|
+
*/
|
|
188
|
+
accessibilityLabel: PropTypes.string,
|
|
189
|
+
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), PropTypes.object]),
|
|
190
|
+
tokens: getTokensPropType('Search'),
|
|
191
|
+
variant: variantProp.propType
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export default Search
|
|
195
|
+
|
|
196
|
+
const staticStyles = StyleSheet.create({
|
|
197
|
+
iconsContainer: {
|
|
198
|
+
position: 'absolute',
|
|
199
|
+
right: 0,
|
|
200
|
+
top: 0,
|
|
201
|
+
bottom: 0,
|
|
202
|
+
justifyContent: 'center'
|
|
203
|
+
}
|
|
204
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
en: {
|
|
3
|
+
accessibilityLabel: 'Search',
|
|
4
|
+
clearButtonAccessibilityLabel: 'Clear',
|
|
5
|
+
submitButtonAccessibilityLabel: 'Search'
|
|
6
|
+
},
|
|
7
|
+
fr: {
|
|
8
|
+
accessibilityLabel: 'Chercher',
|
|
9
|
+
clearButtonAccessibilityLabel: 'Effacer',
|
|
10
|
+
submitButtonAccessibilityLabel: 'Chercher'
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { componentPropType } from '../utils'
|
|
5
|
+
|
|
6
|
+
const Group = ({ children, label }) => {
|
|
7
|
+
return <optgroup label={label}>{children}</optgroup>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default Group
|
|
11
|
+
|
|
12
|
+
Group.propTypes = {
|
|
13
|
+
children: componentPropType('Item'),
|
|
14
|
+
label: PropTypes.string.isRequired
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import PropTypes from 'prop-types'
|
|
2
|
+
|
|
3
|
+
import { componentPropType } from '../utils'
|
|
4
|
+
|
|
5
|
+
const Group = ({ children }) => {
|
|
6
|
+
return children
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default Group
|
|
10
|
+
|
|
11
|
+
Group.propTypes = {
|
|
12
|
+
children: componentPropType('Item'),
|
|
13
|
+
label: PropTypes.string.isRequired
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
const Item = ({ children, value }) => <option value={value}>{children}</option>
|
|
5
|
+
|
|
6
|
+
export default Item
|
|
7
|
+
|
|
8
|
+
Item.propTypes = {
|
|
9
|
+
children: PropTypes.string.isRequired,
|
|
10
|
+
value: PropTypes.string.isRequired
|
|
11
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import PropTypes from 'prop-types'
|
|
4
|
+
import { componentPropType } from '../utils'
|
|
5
|
+
|
|
6
|
+
const Picker = ({
|
|
7
|
+
value,
|
|
8
|
+
onChange,
|
|
9
|
+
onFocus,
|
|
10
|
+
onBlur,
|
|
11
|
+
onMouseOver,
|
|
12
|
+
onMouseOut,
|
|
13
|
+
style,
|
|
14
|
+
inactive,
|
|
15
|
+
children,
|
|
16
|
+
placeholder,
|
|
17
|
+
nativeID,
|
|
18
|
+
testID,
|
|
19
|
+
...rest
|
|
20
|
+
}) => {
|
|
21
|
+
const { accessibilityLabel, accessibilityDescribedBy, accessibilityInvalid } = rest
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<select
|
|
25
|
+
style={style}
|
|
26
|
+
onMouseOver={onMouseOver}
|
|
27
|
+
onMouseOut={onMouseOut}
|
|
28
|
+
onFocus={onFocus}
|
|
29
|
+
onBlur={onBlur}
|
|
30
|
+
disabled={inactive}
|
|
31
|
+
value={value || (placeholder !== undefined ? placeholder.value : undefined)}
|
|
32
|
+
onChange={(event) => onChange(event.target.value)}
|
|
33
|
+
id={nativeID}
|
|
34
|
+
aria-label={accessibilityLabel}
|
|
35
|
+
aria-describedby={accessibilityDescribedBy}
|
|
36
|
+
aria-invalid={accessibilityInvalid}
|
|
37
|
+
data-testid={testID}
|
|
38
|
+
>
|
|
39
|
+
{placeholder !== undefined && (
|
|
40
|
+
<option value={placeholder.value} disabled hidden>
|
|
41
|
+
{placeholder.label}
|
|
42
|
+
</option>
|
|
43
|
+
)}
|
|
44
|
+
{children}
|
|
45
|
+
</select>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default Picker
|
|
50
|
+
|
|
51
|
+
Picker.propTypes = {
|
|
52
|
+
value: PropTypes.string,
|
|
53
|
+
onChange: PropTypes.func,
|
|
54
|
+
onFocus: PropTypes.func,
|
|
55
|
+
onBlur: PropTypes.func,
|
|
56
|
+
onMouseOver: PropTypes.func,
|
|
57
|
+
onMouseOut: PropTypes.func,
|
|
58
|
+
style: PropTypes.object,
|
|
59
|
+
inactive: PropTypes.bool,
|
|
60
|
+
children: componentPropType(['Item', 'Group']),
|
|
61
|
+
placeholder: PropTypes.shape({
|
|
62
|
+
value: PropTypes.string,
|
|
63
|
+
label: PropTypes.string
|
|
64
|
+
}),
|
|
65
|
+
nativeID: PropTypes.string,
|
|
66
|
+
testID: PropTypes.string
|
|
67
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, { Children } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { View, Platform } from 'react-native'
|
|
4
|
+
import NativePicker from 'react-native-picker-select'
|
|
5
|
+
|
|
6
|
+
import { a11yProps, componentPropType } from '../utils'
|
|
7
|
+
import Group from './Group'
|
|
8
|
+
|
|
9
|
+
// styling of the native input is very limited, most of the styles have to be applied to an additional View
|
|
10
|
+
const selectAndroidInputStyles = ({
|
|
11
|
+
height = 0,
|
|
12
|
+
paddingBottom = 0,
|
|
13
|
+
paddingTop = 0,
|
|
14
|
+
borderWidth = 0,
|
|
15
|
+
color
|
|
16
|
+
}) => ({
|
|
17
|
+
height: height - paddingTop - paddingBottom - 2 * borderWidth,
|
|
18
|
+
color
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// the native input has a side padding of 8px, which can't be adjusted, so we have to account for that in the container
|
|
22
|
+
const selectAndroidContainerStyles = ({ paddingLeft = 0, paddingRight = 0, ...rest }) => ({
|
|
23
|
+
paddingLeft: paddingLeft > 8 ? paddingLeft - 8 : 0,
|
|
24
|
+
paddingRight: paddingRight > 8 ? paddingRight - 8 : 0,
|
|
25
|
+
...rest
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const Picker = ({
|
|
29
|
+
value,
|
|
30
|
+
onChange,
|
|
31
|
+
onFocus,
|
|
32
|
+
onBlur,
|
|
33
|
+
style,
|
|
34
|
+
inactive,
|
|
35
|
+
children,
|
|
36
|
+
placeholder,
|
|
37
|
+
...rest
|
|
38
|
+
}) => {
|
|
39
|
+
// ungroup items, since there's no way to support groups on native
|
|
40
|
+
const flatChildren = Children.toArray(children).flatMap((child) => {
|
|
41
|
+
if (child.type === Group) {
|
|
42
|
+
return child.props.children
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return child
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const items = flatChildren.map(({ props }) => ({
|
|
49
|
+
label: props.children,
|
|
50
|
+
value: props.value
|
|
51
|
+
}))
|
|
52
|
+
|
|
53
|
+
const picker = (
|
|
54
|
+
<NativePicker
|
|
55
|
+
touchableWrapperProps={a11yProps.select(rest)}
|
|
56
|
+
onOpen={onFocus}
|
|
57
|
+
onClose={onBlur}
|
|
58
|
+
disabled={inactive}
|
|
59
|
+
items={items}
|
|
60
|
+
value={value}
|
|
61
|
+
onValueChange={onChange}
|
|
62
|
+
style={{
|
|
63
|
+
inputIOS: style,
|
|
64
|
+
inputAndroid: selectAndroidInputStyles(style)
|
|
65
|
+
}}
|
|
66
|
+
placeholder={placeholder !== undefined ? placeholder : {}}
|
|
67
|
+
/>
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<>
|
|
72
|
+
{Platform.OS === 'android' ? (
|
|
73
|
+
<View style={selectAndroidContainerStyles(style)}>{picker}</View>
|
|
74
|
+
) : (
|
|
75
|
+
picker
|
|
76
|
+
)}
|
|
77
|
+
</>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default Picker
|
|
82
|
+
|
|
83
|
+
Picker.propTypes = {
|
|
84
|
+
value: PropTypes.string,
|
|
85
|
+
onChange: PropTypes.func,
|
|
86
|
+
onFocus: PropTypes.func,
|
|
87
|
+
onBlur: PropTypes.func,
|
|
88
|
+
style: PropTypes.object,
|
|
89
|
+
inactive: PropTypes.bool,
|
|
90
|
+
children: componentPropType(['Item', 'Group']),
|
|
91
|
+
placeholder: PropTypes.shape({
|
|
92
|
+
value: PropTypes.string,
|
|
93
|
+
label: PropTypes.string
|
|
94
|
+
})
|
|
95
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { View, Platform, StyleSheet } from 'react-native'
|
|
4
|
+
import PropTypes from 'prop-types'
|
|
5
|
+
import { applyTextStyles, useThemeTokens, applyOuterBorder } from '../ThemeProvider'
|
|
6
|
+
import { componentPropType, getTokensPropType, useInputValue, variantProp } from '../utils'
|
|
7
|
+
import Picker from './Picker'
|
|
8
|
+
import InputSupports from '../InputSupports'
|
|
9
|
+
import inputSupportsProps from '../InputSupports/propTypes'
|
|
10
|
+
|
|
11
|
+
const selectInputStyles = (
|
|
12
|
+
{
|
|
13
|
+
backgroundColor,
|
|
14
|
+
color,
|
|
15
|
+
borderWidth = 0,
|
|
16
|
+
borderColor,
|
|
17
|
+
borderRadius,
|
|
18
|
+
paddingTop,
|
|
19
|
+
paddingBottom,
|
|
20
|
+
paddingLeft = 0,
|
|
21
|
+
paddingRight,
|
|
22
|
+
fontName,
|
|
23
|
+
fontSize,
|
|
24
|
+
fontWeight,
|
|
25
|
+
lineHeight,
|
|
26
|
+
icon,
|
|
27
|
+
iconSize = 0,
|
|
28
|
+
validationIcon,
|
|
29
|
+
validationIconSize = 0,
|
|
30
|
+
height
|
|
31
|
+
},
|
|
32
|
+
inactive
|
|
33
|
+
) => {
|
|
34
|
+
// Subtract border width from padding so overall input width/height doesn't
|
|
35
|
+
// jump around if the border width changes (avoiding NaN and negative padding)
|
|
36
|
+
const offsetBorder = (value) =>
|
|
37
|
+
typeof value === 'number' ? Math.max(0, value - borderWidth) : value
|
|
38
|
+
|
|
39
|
+
const textStyles = applyTextStyles({ fontName, fontSize, lineHeight, fontWeight })
|
|
40
|
+
|
|
41
|
+
const webStyles = Platform.select({
|
|
42
|
+
web: {
|
|
43
|
+
appearance: 'none',
|
|
44
|
+
WebkitAppearance: 'none', // since iOS Safari needs a prefix
|
|
45
|
+
outline: 'none',
|
|
46
|
+
cursor: inactive ? 'not-allowed' : undefined,
|
|
47
|
+
opacity: inactive ? 1 : undefined // override Chrome's default fadeout of a disabled select
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
let paddingWithIcons = paddingRight
|
|
52
|
+
|
|
53
|
+
if (Platform.OS !== 'android') {
|
|
54
|
+
if (icon) {
|
|
55
|
+
paddingWithIcons += iconSize
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (validationIcon) {
|
|
59
|
+
paddingWithIcons += validationIconSize
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
backgroundColor,
|
|
65
|
+
color,
|
|
66
|
+
borderWidth,
|
|
67
|
+
borderColor,
|
|
68
|
+
borderRadius,
|
|
69
|
+
paddingLeft: offsetBorder(paddingLeft),
|
|
70
|
+
paddingRight: offsetBorder(paddingWithIcons),
|
|
71
|
+
paddingTop: offsetBorder(paddingTop),
|
|
72
|
+
paddingBottom: offsetBorder(paddingBottom),
|
|
73
|
+
height,
|
|
74
|
+
...textStyles,
|
|
75
|
+
...webStyles
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const selectOuterBorderStyles = ({
|
|
80
|
+
outerBackgroundColor,
|
|
81
|
+
outerBorderWidth,
|
|
82
|
+
outerBorderColor,
|
|
83
|
+
borderRadius
|
|
84
|
+
}) => ({
|
|
85
|
+
background: outerBackgroundColor,
|
|
86
|
+
...applyOuterBorder({
|
|
87
|
+
outerBorderColor,
|
|
88
|
+
outerBorderWidth,
|
|
89
|
+
borderRadius
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const selectIconTokens = ({ iconSize, iconColor }) => ({
|
|
94
|
+
size: iconSize,
|
|
95
|
+
color: iconColor
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const selectIconContainerStyles = ({ paddingRight, paddingBottom }) => ({
|
|
99
|
+
paddingRight,
|
|
100
|
+
paddingBottom
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
const selectValidationIconTokens = ({ validationIconSize, validationIconColor }) => ({
|
|
104
|
+
size: validationIconSize,
|
|
105
|
+
color: validationIconColor
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
const selectValidationIconContainerStyles = ({
|
|
109
|
+
icon,
|
|
110
|
+
iconSize = 0,
|
|
111
|
+
paddingRight = 0,
|
|
112
|
+
paddingBottom
|
|
113
|
+
}) => ({
|
|
114
|
+
paddingRight: icon ? paddingRight + iconSize : paddingRight,
|
|
115
|
+
paddingBottom
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* A basic form single-choice select component. Use in forms or individually to receive user's input.
|
|
120
|
+
*
|
|
121
|
+
* ## Usage criteria
|
|
122
|
+
* - Include a `placeholder` to provide instructions such as "Please select..." as an unselectable option (recommended)
|
|
123
|
+
* - Use when options are between 7-15 (recommended)
|
|
124
|
+
* - For options are 6 and under, use `Radio` groups or `ButtonGroup`.
|
|
125
|
+
* - For options 15 and above, look for alternatives (e.g grouping into categories, or input field with auto-complete etc.)
|
|
126
|
+
*
|
|
127
|
+
* ## Controlled component
|
|
128
|
+
* If it is required that the state of the `Select` be controlled by the application or other external methods,
|
|
129
|
+
* `value` and `onChange` props must be passed to the `Select`.
|
|
130
|
+
* If the `Select` value should not be changed by user input, a `readOnly` prop must be provided.
|
|
131
|
+
*
|
|
132
|
+
* ## Uncontrolled component
|
|
133
|
+
* If it is not necessary to control the `Select` state, you can create one without a value prop.
|
|
134
|
+
* In this case its value can be accessed within the `onChange` callback. Use the `initialValue` prop to set the
|
|
135
|
+
* default value for an uncontrolled `Select`.
|
|
136
|
+
*
|
|
137
|
+
* ## Getting feedback for entered values
|
|
138
|
+
* Use the `feedback` prop to give the user feedback regarding their selection.
|
|
139
|
+
* You can affirm that the user's selection was correct, or highlight errors that must be corrected, using the `validation` prop.
|
|
140
|
+
* Keep feedback text as brief as possible, should be limited to text and links.
|
|
141
|
+
*
|
|
142
|
+
* ## Using a tooltip
|
|
143
|
+
* When a more in-depth explanation is needed to fill out a `Select` properly, the tooltip prop may be used.
|
|
144
|
+
*
|
|
145
|
+
* ## Grouping options
|
|
146
|
+
* `Select` supports option groups. Use a `Select.Group` component to render an `<optgroup>` element with its items.
|
|
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
|
+
*
|
|
149
|
+
*/
|
|
150
|
+
const Select = ({
|
|
151
|
+
value,
|
|
152
|
+
initialValue,
|
|
153
|
+
onChange,
|
|
154
|
+
children,
|
|
155
|
+
inactive,
|
|
156
|
+
readOnly,
|
|
157
|
+
placeholder,
|
|
158
|
+
validation,
|
|
159
|
+
tokens,
|
|
160
|
+
variant,
|
|
161
|
+
testID,
|
|
162
|
+
...rest
|
|
163
|
+
}) => {
|
|
164
|
+
const { currentValue, setValue } = useInputValue({
|
|
165
|
+
value,
|
|
166
|
+
initialValue,
|
|
167
|
+
onChange,
|
|
168
|
+
readOnly
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
const [isFocused, setIsFocused] = useState(false)
|
|
172
|
+
const handleFocus = () => setIsFocused(true)
|
|
173
|
+
const handleBlur = () => setIsFocused(false)
|
|
174
|
+
|
|
175
|
+
const [isHovered, setIsHovered] = useState(false)
|
|
176
|
+
const handleMouseOver = () => setIsHovered(true)
|
|
177
|
+
const handleMouseOut = () => setIsHovered(false)
|
|
178
|
+
|
|
179
|
+
const { props: supportsProps } = inputSupportsProps.select(rest)
|
|
180
|
+
|
|
181
|
+
const themeTokens = useThemeTokens('Select', tokens, variant, {
|
|
182
|
+
focus: isFocused,
|
|
183
|
+
hover: isHovered,
|
|
184
|
+
inactive,
|
|
185
|
+
validation
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
const { icon: IconComponent, validationIcon: ValidationIconComponent } = themeTokens
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<InputSupports {...supportsProps}>
|
|
192
|
+
{({ a11yProps, inputId }) => (
|
|
193
|
+
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
194
|
+
<Picker
|
|
195
|
+
style={selectInputStyles(themeTokens, inactive)}
|
|
196
|
+
onFocus={handleFocus}
|
|
197
|
+
onBlur={handleBlur}
|
|
198
|
+
onMouseOver={handleMouseOver}
|
|
199
|
+
onMouseOut={handleMouseOut}
|
|
200
|
+
onChange={setValue}
|
|
201
|
+
value={currentValue}
|
|
202
|
+
inactive={inactive}
|
|
203
|
+
placeholder={placeholder !== undefined ? { label: placeholder, value: '' } : undefined}
|
|
204
|
+
{...a11yProps}
|
|
205
|
+
nativeID={inputId}
|
|
206
|
+
testID={testID}
|
|
207
|
+
>
|
|
208
|
+
{children}
|
|
209
|
+
</Picker>
|
|
210
|
+
{ValidationIconComponent && (
|
|
211
|
+
<View
|
|
212
|
+
pointerEvents="none"
|
|
213
|
+
style={[staticStyles.iconContainer, selectValidationIconContainerStyles(themeTokens)]}
|
|
214
|
+
>
|
|
215
|
+
<ValidationIconComponent tokens={selectValidationIconTokens(themeTokens)} />
|
|
216
|
+
</View>
|
|
217
|
+
)}
|
|
218
|
+
{IconComponent &&
|
|
219
|
+
Platform.OS !== 'android' && ( // we can't hide the default caret of a native picker on android
|
|
220
|
+
<View
|
|
221
|
+
pointerEvents="none"
|
|
222
|
+
style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
|
|
223
|
+
>
|
|
224
|
+
<IconComponent {...selectIconTokens(themeTokens)} />
|
|
225
|
+
</View>
|
|
226
|
+
)}
|
|
227
|
+
</View>
|
|
228
|
+
)}
|
|
229
|
+
</InputSupports>
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
Select.propTypes = {
|
|
234
|
+
...inputSupportsProps.types,
|
|
235
|
+
initialValue: PropTypes.string,
|
|
236
|
+
value: PropTypes.string,
|
|
237
|
+
onChange: PropTypes.func,
|
|
238
|
+
children: componentPropType(['Item', 'Group']),
|
|
239
|
+
inactive: PropTypes.bool,
|
|
240
|
+
readOnly: PropTypes.bool,
|
|
241
|
+
placeholder: PropTypes.string,
|
|
242
|
+
tokens: getTokensPropType('Select'),
|
|
243
|
+
variant: variantProp.propType,
|
|
244
|
+
testID: PropTypes.string
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export default Select
|
|
248
|
+
|
|
249
|
+
const staticStyles = StyleSheet.create({
|
|
250
|
+
iconContainer: {
|
|
251
|
+
position: 'absolute',
|
|
252
|
+
right: 0,
|
|
253
|
+
bottom: 0
|
|
254
|
+
}
|
|
255
|
+
})
|