@telus-uds/components-base 0.0.2-prerelease.7 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +9 -0
- package/.ultra.cache.json +1 -1
- package/CHANGELOG.md +71 -0
- package/README.md +4 -2
- package/__fixtures__/Accessible.js +33 -0
- package/__fixtures__/Accessible.native.js +32 -0
- package/__fixtures__/test-utils.js +25 -0
- package/__fixtures__/testTheme.js +438 -31
- package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
- package/__tests__/Button/ButtonGroup.test.jsx +6 -7
- package/__tests__/Checkbox/Checkbox.test.jsx +2 -2
- package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
- package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
- package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
- package/__tests__/Icon/Icon.test.jsx +3 -3
- package/__tests__/IconButton/IconButton.test.jsx +52 -0
- package/__tests__/Link/LinkBase.test.jsx +0 -14
- 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 +2 -2
- package/__tests__/Radio/RadioGroup.test.jsx +220 -0
- package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
- package/__tests__/RadioCard/RadioCardGroup.test.jsx +246 -0
- package/__tests__/Search/Search.test.jsx +73 -0
- package/__tests__/Select/Select.test.jsx +3 -2
- package/__tests__/Skeleton/Skeleton.test.jsx +1 -1
- package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
- package/__tests__/Tabs/Tabs.test.jsx +40 -0
- package/__tests__/Tags/Tags.test.jsx +5 -6
- 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 +59 -1
- package/__tests__/utils/semantics.test.jsx +43 -0
- package/__tests__/utils/useCopy.test.js +14 -3
- package/babel.config.js +20 -0
- package/jest.config.js +6 -3
- package/lib/A11yInfoProvider/index.js +54 -26
- package/lib/A11yText/index.js +45 -17
- package/lib/ActivityIndicator/Spinner.js +81 -0
- package/lib/ActivityIndicator/Spinner.native.js +129 -91
- 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 +153 -35
- package/lib/Box/index.js +13 -2
- package/lib/Button/Button.js +38 -16
- package/lib/Button/ButtonBase.js +93 -79
- package/lib/Button/ButtonGroup.js +112 -73
- package/lib/Button/ButtonLink.js +45 -19
- package/lib/Button/index.js +31 -4
- package/lib/Button/propTypes.js +32 -9
- package/lib/Card/Card.js +38 -41
- package/lib/Card/CardBase.js +86 -0
- package/lib/Card/PressableCardBase.js +141 -0
- package/lib/Card/index.js +40 -2
- package/lib/Checkbox/Checkbox.js +158 -111
- package/lib/Checkbox/CheckboxGroup.js +241 -0
- package/lib/Checkbox/CheckboxInput.js +74 -0
- package/lib/Checkbox/CheckboxInput.native.js +9 -1
- package/lib/Checkbox/index.js +21 -2
- package/lib/Divider/Divider.js +59 -28
- package/lib/Divider/index.js +13 -2
- package/lib/ExpandCollapse/Accordion.js +26 -7
- package/lib/ExpandCollapse/Control.js +60 -31
- package/lib/ExpandCollapse/ExpandCollapse.js +50 -28
- package/lib/ExpandCollapse/Panel.js +83 -44
- package/lib/ExpandCollapse/index.js +25 -7
- package/lib/Feedback/Feedback.js +77 -43
- package/lib/Feedback/index.js +13 -2
- package/lib/Fieldset/Fieldset.js +165 -0
- package/lib/Fieldset/FieldsetContainer.js +46 -0
- package/lib/Fieldset/FieldsetContainer.native.js +38 -0
- package/lib/Fieldset/Legend.js +38 -0
- package/lib/Fieldset/Legend.native.js +48 -0
- package/lib/Fieldset/cssReset.js +21 -0
- package/lib/Fieldset/index.js +13 -0
- package/lib/FlexGrid/Col/Col.js +73 -41
- package/lib/FlexGrid/Col/index.js +13 -2
- package/lib/FlexGrid/FlexGrid.js +99 -49
- package/lib/FlexGrid/Row/Row.js +58 -30
- 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/HorizontalScroll/HorizontalScroll.js +200 -0
- package/lib/HorizontalScroll/HorizontalScrollButton.js +127 -0
- package/lib/HorizontalScroll/ScrollViewEnd.js +66 -0
- package/lib/HorizontalScroll/ScrollViewEnd.native.js +41 -0
- package/lib/HorizontalScroll/dictionary.js +18 -0
- package/lib/HorizontalScroll/index.js +35 -0
- package/lib/HorizontalScroll/itemPositions.js +128 -0
- package/lib/Icon/Icon.js +57 -48
- package/lib/Icon/IconText.js +54 -25
- package/lib/Icon/index.js +31 -4
- package/lib/IconButton/IconButton.js +140 -0
- package/lib/IconButton/index.js +13 -0
- package/lib/InputLabel/InputLabel.js +102 -40
- package/lib/InputLabel/LabelContent.js +41 -0
- package/lib/InputLabel/LabelContent.native.js +32 -6
- package/lib/InputLabel/index.js +13 -2
- package/lib/InputSupports/InputSupports.js +71 -52
- package/lib/InputSupports/index.js +13 -2
- package/lib/InputSupports/propTypes.js +19 -8
- package/lib/InputSupports/useInputSupports.js +41 -0
- package/lib/Link/ChevronLink.js +44 -20
- package/lib/Link/InlinePressable.js +56 -0
- package/lib/Link/InlinePressable.native.js +39 -15
- package/lib/Link/Link.js +36 -13
- package/lib/Link/LinkBase.js +98 -61
- package/lib/Link/TextButton.js +41 -17
- package/lib/Link/index.js +39 -5
- package/lib/List/List.js +55 -26
- package/lib/List/ListItem.js +79 -41
- package/lib/List/index.js +13 -2
- package/lib/Modal/Modal.js +231 -0
- package/lib/Modal/dictionary.js +16 -0
- package/lib/Modal/index.js +13 -0
- package/lib/Notification/Notification.js +216 -0
- package/lib/Notification/dictionary.js +15 -0
- package/lib/Notification/index.js +13 -0
- package/lib/Pagination/PageButton.js +61 -28
- package/lib/Pagination/Pagination.js +78 -43
- package/lib/Pagination/SideButton.js +73 -42
- 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 +104 -0
- package/lib/Progress/ProgressBar.js +157 -0
- package/lib/Progress/ProgressBarBackground.js +61 -0
- package/lib/Progress/index.js +16 -0
- package/lib/Radio/Radio.js +116 -114
- package/lib/Radio/RadioButton.js +152 -0
- package/lib/Radio/RadioGroup.js +244 -0
- package/lib/Radio/RadioInput.js +76 -0
- package/lib/Radio/RadioInput.native.js +9 -1
- package/lib/Radio/index.js +21 -2
- package/lib/RadioCard/RadioCard.js +244 -0
- package/lib/RadioCard/RadioCardGroup.js +252 -0
- package/lib/RadioCard/index.js +21 -0
- package/lib/Search/Search.js +254 -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 +16 -5
- package/lib/Select/Item.js +29 -0
- package/lib/Select/Item.native.js +14 -4
- package/lib/Select/Picker.js +84 -0
- package/lib/Select/Picker.native.js +73 -30
- package/lib/Select/Select.js +155 -85
- package/lib/Select/index.js +19 -6
- package/lib/SideNav/Item.js +63 -37
- package/lib/SideNav/ItemContent.js +41 -15
- package/lib/SideNav/ItemsGroup.js +55 -31
- package/lib/SideNav/SideNav.js +100 -73
- package/lib/SideNav/index.js +15 -1
- package/lib/Skeleton/Skeleton.js +64 -46
- package/lib/Skeleton/index.js +13 -2
- 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 +49 -18
- package/lib/Spacer/index.js +13 -2
- package/lib/StackView/StackView.js +72 -31
- package/lib/StackView/StackWrap.js +43 -13
- package/lib/StackView/StackWrap.native.js +13 -2
- package/lib/StackView/StackWrapBox.js +77 -29
- package/lib/StackView/StackWrapGap.js +56 -26
- package/lib/StackView/common.js +23 -6
- package/lib/StackView/getStackedContent.js +47 -17
- package/lib/StackView/index.js +29 -5
- package/lib/StepTracker/Step.js +245 -0
- package/lib/StepTracker/StepTracker.js +202 -0
- package/lib/StepTracker/dictionary.js +17 -0
- package/lib/StepTracker/index.js +13 -0
- package/lib/Tabs/Tabs.js +124 -0
- package/lib/Tabs/TabsItem.js +238 -0
- package/lib/Tabs/index.js +13 -0
- package/lib/Tags/Tags.js +148 -99
- package/lib/Tags/index.js +13 -2
- package/lib/TextInput/TextArea.js +57 -28
- package/lib/TextInput/TextInput.js +50 -23
- package/lib/TextInput/TextInputBase.js +90 -63
- package/lib/TextInput/index.js +23 -3
- package/lib/TextInput/propTypes.js +18 -7
- package/lib/ThemeProvider/ThemeProvider.js +46 -18
- package/lib/ThemeProvider/index.js +61 -6
- package/lib/ThemeProvider/useSetTheme.js +19 -5
- package/lib/ThemeProvider/useTheme.js +13 -4
- package/lib/ThemeProvider/useThemeTokens.js +32 -16
- package/lib/ThemeProvider/utils/index.js +31 -2
- package/lib/ThemeProvider/utils/styles.js +50 -14
- package/lib/ThemeProvider/utils/theme-tokens.js +121 -12
- package/lib/ToggleSwitch/ToggleSwitch.js +85 -56
- package/lib/ToggleSwitch/index.js +13 -2
- package/lib/Tooltip/{Backdrop.web.js → Backdrop.js} +20 -8
- package/lib/Tooltip/Backdrop.native.js +39 -15
- package/lib/Tooltip/Tooltip.js +117 -74
- package/lib/Tooltip/dictionary.js +9 -2
- package/lib/Tooltip/getTooltipPosition.js +9 -1
- package/lib/Tooltip/index.js +13 -2
- package/lib/TooltipButton/TooltipButton.js +57 -38
- package/lib/TooltipButton/index.js +13 -2
- package/lib/Typography/Typography.js +87 -41
- package/lib/Typography/index.js +13 -2
- package/lib/ViewportProvider/ViewportProvider.js +34 -13
- package/lib/ViewportProvider/index.js +28 -3
- package/lib/ViewportProvider/useViewport.js +15 -3
- package/lib/ViewportProvider/useViewportListener.js +24 -10
- package/lib/index.js +539 -33
- package/lib/utils/a11y/index.js +31 -1
- package/lib/utils/a11y/semantics.js +173 -0
- package/lib/utils/a11y/textSize.js +23 -7
- package/lib/utils/animation/index.js +15 -2
- package/lib/utils/animation/useVerticalExpandAnimation.js +27 -10
- package/lib/utils/children.js +134 -0
- package/lib/utils/index.js +163 -10
- package/lib/utils/info/index.js +18 -6
- package/lib/utils/info/platform/index.js +19 -7
- package/lib/utils/info/platform/platform.android.js +8 -1
- package/lib/utils/info/platform/platform.ios.js +8 -1
- package/lib/utils/info/platform/platform.js +8 -0
- package/lib/utils/info/platform/platform.native.js +8 -1
- package/lib/utils/info/versions.js +15 -4
- package/lib/utils/input.js +53 -25
- package/lib/utils/pressability.js +38 -10
- package/lib/utils/propTypes.js +287 -141
- package/lib/utils/useCopy.js +40 -5
- package/lib/utils/useHash.js +52 -0
- package/lib/utils/useHash.native.js +15 -0
- package/lib/utils/useResponsiveProp.js +21 -9
- package/lib/utils/useSpacingScale.js +19 -9
- package/lib/utils/useUniqueId.js +12 -3
- package/package.json +14 -9
- package/release-context.json +4 -4
- package/src/A11yText/index.jsx +6 -4
- package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +5 -3
- package/src/ActivityIndicator/Spinner.native.jsx +5 -3
- package/src/Box/Box.jsx +132 -39
- package/src/Button/Button.jsx +10 -6
- package/src/Button/ButtonBase.jsx +99 -99
- package/src/Button/ButtonGroup.jsx +81 -69
- package/src/Button/ButtonLink.jsx +21 -15
- package/src/Button/propTypes.js +12 -2
- package/src/Card/Card.jsx +5 -31
- package/src/Card/CardBase.jsx +59 -0
- package/src/Card/PressableCardBase.jsx +119 -0
- package/src/Card/index.js +3 -0
- package/src/Checkbox/Checkbox.jsx +121 -112
- package/src/Checkbox/CheckboxGroup.jsx +206 -0
- package/src/Checkbox/{CheckboxInput.web.jsx → CheckboxInput.jsx} +0 -0
- package/src/Checkbox/index.js +2 -0
- 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 +136 -0
- package/src/Fieldset/FieldsetContainer.jsx +31 -0
- package/src/Fieldset/FieldsetContainer.native.jsx +19 -0
- package/src/Fieldset/Legend.jsx +21 -0
- package/src/Fieldset/Legend.native.jsx +27 -0
- package/src/Fieldset/cssReset.js +14 -0
- package/src/Fieldset/index.js +3 -0
- 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/HorizontalScroll/ScrollViewEnd.jsx +53 -0
- package/src/HorizontalScroll/ScrollViewEnd.native.jsx +24 -0
- package/src/HorizontalScroll/dictionary.js +11 -0
- package/src/HorizontalScroll/index.js +17 -0
- package/src/HorizontalScroll/itemPositions.js +101 -0
- package/src/Icon/Icon.jsx +43 -50
- package/src/Icon/IconText.jsx +23 -18
- package/src/Icon/index.js +2 -2
- package/src/IconButton/IconButton.jsx +114 -0
- package/src/IconButton/index.js +3 -0
- package/src/InputLabel/InputLabel.jsx +57 -35
- package/src/InputLabel/LabelContent.jsx +21 -0
- package/src/InputLabel/LabelContent.native.jsx +11 -2
- package/src/InputSupports/InputSupports.jsx +29 -45
- package/src/InputSupports/useInputSupports.js +30 -0
- package/src/Link/ChevronLink.jsx +26 -16
- package/src/Link/{InlinePressable.web.jsx → InlinePressable.jsx} +5 -3
- package/src/Link/InlinePressable.native.jsx +5 -3
- package/src/Link/Link.jsx +22 -16
- package/src/Link/LinkBase.jsx +76 -65
- package/src/Link/TextButton.jsx +30 -23
- package/src/List/List.jsx +5 -4
- package/src/List/ListItem.jsx +77 -82
- package/src/Modal/Modal.jsx +190 -0
- package/src/Modal/dictionary.js +9 -0
- package/src/Modal/index.js +3 -0
- package/src/Notification/Notification.jsx +164 -0
- package/src/Notification/dictionary.js +8 -0
- package/src/Notification/index.js +3 -0
- package/src/Pagination/PageButton.jsx +42 -35
- package/src/Pagination/Pagination.jsx +88 -92
- package/src/Pagination/SideButton.jsx +44 -41
- package/src/Progress/Progress.jsx +78 -0
- package/src/Progress/ProgressBar.jsx +123 -0
- package/src/Progress/ProgressBarBackground.jsx +36 -0
- package/src/Progress/index.js +6 -0
- package/src/Radio/Radio.jsx +82 -112
- package/src/Radio/RadioButton.jsx +142 -0
- package/src/Radio/RadioGroup.jsx +209 -0
- package/src/Radio/{RadioInput.web.jsx → RadioInput.jsx} +0 -0
- package/src/Radio/index.js +2 -0
- package/src/RadioCard/RadioCard.jsx +198 -0
- package/src/RadioCard/RadioCardGroup.jsx +218 -0
- package/src/RadioCard/index.js +5 -0
- package/src/Search/Search.jsx +225 -0
- package/src/Search/dictionary.js +12 -0
- package/src/Search/index.js +3 -0
- package/src/Select/{Group.web.jsx → Group.jsx} +0 -0
- package/src/Select/{Item.web.jsx → Item.jsx} +0 -0
- package/src/Select/Picker.jsx +74 -0
- package/src/Select/Picker.native.jsx +56 -49
- package/src/Select/Select.jsx +125 -92
- package/src/SideNav/Item.jsx +54 -47
- package/src/SideNav/ItemsGroup.jsx +50 -43
- package/src/SideNav/SideNav.jsx +68 -60
- package/src/Skeleton/Skeleton.jsx +25 -32
- 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 +11 -4
- package/src/StackView/StackView.jsx +54 -23
- package/src/StackView/StackWrap.jsx +16 -7
- package/src/StackView/StackWrapBox.jsx +63 -28
- package/src/StackView/StackWrapGap.jsx +46 -24
- package/src/StackView/common.jsx +3 -2
- package/src/StackView/getStackedContent.jsx +8 -2
- package/src/StepTracker/Step.jsx +202 -0
- package/src/StepTracker/StepTracker.jsx +174 -0
- package/src/StepTracker/dictionary.js +10 -0
- package/src/StepTracker/index.js +3 -0
- package/src/Tabs/Tabs.jsx +97 -0
- package/src/Tabs/TabsItem.jsx +212 -0
- package/src/Tabs/index.js +3 -0
- package/src/Tags/Tags.jsx +115 -102
- package/src/TextInput/TextArea.jsx +5 -4
- package/src/TextInput/TextInput.jsx +5 -4
- package/src/TextInput/TextInputBase.jsx +95 -98
- package/src/ThemeProvider/ThemeProvider.jsx +11 -7
- package/src/ThemeProvider/useSetTheme.js +4 -0
- package/src/ThemeProvider/useThemeTokens.js +2 -2
- package/src/ThemeProvider/utils/styles.js +18 -5
- package/src/ThemeProvider/utils/theme-tokens.js +74 -5
- package/src/ToggleSwitch/ToggleSwitch.jsx +50 -52
- package/src/Tooltip/{Backdrop.web.jsx → Backdrop.jsx} +0 -0
- package/src/Tooltip/Tooltip.jsx +135 -131
- package/src/TooltipButton/TooltipButton.jsx +23 -27
- package/src/Typography/Typography.jsx +71 -47
- package/src/index.js +23 -2
- package/src/utils/a11y/index.js +1 -0
- package/src/utils/a11y/semantics.js +162 -0
- package/src/utils/children.jsx +119 -0
- package/src/utils/index.js +3 -0
- package/src/utils/info/platform/platform.js +1 -0
- package/src/utils/info/versions.js +2 -2
- package/src/utils/input.js +36 -25
- package/src/utils/pressability.js +4 -0
- package/src/utils/propTypes.js +199 -72
- package/src/utils/useCopy.js +30 -4
- package/src/utils/useHash.js +39 -0
- package/src/utils/useHash.native.js +6 -0
- package/stories/A11yText/A11yText.stories.jsx +6 -10
- package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +1 -1
- package/stories/Box/Box.stories.jsx +1 -1
- package/stories/Button/Button.stories.jsx +2 -2
- package/stories/Button/ButtonGroup.stories.jsx +1 -1
- package/stories/Button/ButtonLink.stories.jsx +1 -1
- package/stories/Card/Card.stories.jsx +1 -1
- package/stories/Checkbox/Checkbox.stories.jsx +24 -1
- package/stories/Divider/Divider.stories.jsx +1 -1
- package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +2 -2
- package/stories/Feedback/Feedback.stories.jsx +1 -1
- package/stories/FlexGrid/01 FlexGrid.stories.jsx +1 -1
- package/stories/FlexGrid/02 Row.stories.jsx +1 -1
- package/stories/FlexGrid/03 Col.stories.jsx +1 -1
- package/stories/Icon/Icon.stories.jsx +27 -7
- package/stories/IconButton/IconButton.stories.jsx +50 -0
- package/stories/InputLabel/InputLabel.stories.jsx +1 -1
- package/stories/Link/ChevronLink.stories.jsx +1 -1
- package/stories/Link/Link.stories.jsx +17 -21
- package/stories/Link/TextButton.stories.jsx +1 -1
- package/stories/List/List.stories.jsx +1 -1
- package/stories/Modal/Modal.stories.jsx +29 -0
- package/stories/Notification/Notification.stories.jsx +82 -0
- package/stories/Pagination/Pagination.stories.jsx +1 -1
- package/stories/Progress/Progress.stories.jsx +93 -0
- package/stories/Radio/Radio.stories.jsx +23 -36
- package/stories/RadioCard/RadioCard.stories.jsx +98 -0
- package/stories/Search/Search.stories.jsx +16 -0
- package/stories/Select/Select.stories.jsx +1 -1
- package/stories/SideNav/SideNav.stories.jsx +1 -1
- package/stories/SideNav/SideNavItem.stories.jsx +1 -1
- package/stories/SideNav/SideNavItemsGroup.stories.jsx +1 -1
- package/stories/Skeleton/Skeleton.stories.jsx +2 -2
- package/stories/Spacer/Spacer.stories.jsx +1 -1
- package/stories/StackView/StackView.stories.jsx +1 -1
- package/stories/StackView/StackWrap.stories.jsx +1 -1
- package/stories/StepTracker/StepTracker.stories.jsx +71 -0
- package/stories/Tabs/Tabs.stories.jsx +97 -0
- package/stories/Tags/Tags.stories.jsx +1 -1
- package/stories/TextInput/TextArea.stories.jsx +1 -1
- package/stories/TextInput/TextInput.stories.jsx +1 -1
- package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +1 -1
- package/stories/Tooltip/Tooltip.stories.jsx +1 -1
- package/stories/TooltipButton/TooltipButton.stories.jsx +1 -1
- package/stories/Typography/Typography.stories.jsx +1 -1
- package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
- package/stories/supports.jsx +37 -3
- package/__fixtures__/accessible.icon.svg +0 -6
- package/babel.config.json +0 -8
- package/docs/Contributing.stories.mdx +0 -9
- package/docs/Fonts.stories.mdx +0 -104
- package/docs/Icons.stories.mdx +0 -144
- package/docs/Introduction.stories.mdx +0 -9
- package/lib/ActivityIndicator/Spinner.web.js +0 -55
- package/lib/Checkbox/CheckboxInput.web.js +0 -57
- package/lib/InputLabel/LabelContent.web.js +0 -17
- package/lib/Link/InlinePressable.web.js +0 -32
- package/lib/Radio/RadioInput.web.js +0 -59
- package/lib/Select/Group.web.js +0 -18
- package/lib/Select/Item.web.js +0 -15
- package/lib/Select/Picker.web.js +0 -63
- package/lib/config/svgr-icons-web.js +0 -9
- package/lib/config/svgr-icons.js +0 -52
- package/lib/utils/info/platform/platform.web.js +0 -1
- package/src/InputLabel/LabelContent.web.jsx +0 -13
- package/src/Select/Picker.web.jsx +0 -67
- package/src/config/svgr-icons-web.js +0 -11
- package/src/config/svgr-icons.js +0 -46
- package/src/utils/info/platform/platform.web.js +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, within } from '@testing-library/react-native'
|
|
3
|
+
|
|
4
|
+
import { StepTracker } from '../../src'
|
|
5
|
+
import Theme from '../../__fixtures__/Theme'
|
|
6
|
+
import Viewport from '../../__fixtures__/Viewport'
|
|
7
|
+
import dictionary from '../../src/StepTracker/dictionary'
|
|
8
|
+
|
|
9
|
+
const defaultSteps = [...Array(5).keys()].map((key) => `Some Step Title ${key + 1}`)
|
|
10
|
+
|
|
11
|
+
const setup = ({ current, steps = defaultSteps, tokens, viewport }) =>
|
|
12
|
+
render(
|
|
13
|
+
<Theme>
|
|
14
|
+
<Viewport viewport={viewport}>
|
|
15
|
+
<StepTracker current={current} steps={steps} tokens={tokens} />
|
|
16
|
+
</Viewport>
|
|
17
|
+
</Theme>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
describe('StepTracker', () => {
|
|
21
|
+
const currentStep = 2
|
|
22
|
+
|
|
23
|
+
it('renders the steps properly', () => {
|
|
24
|
+
const { getAllByTestId, getByA11yLabel } = setup({ current: currentStep })
|
|
25
|
+
|
|
26
|
+
expect(getAllByTestId(/StepTracker-Step/).length).toBe(defaultSteps.length)
|
|
27
|
+
expect(getAllByTestId(/StepTracker-Step-Completed/).length).toBe(
|
|
28
|
+
defaultSteps.length - currentStep - 1
|
|
29
|
+
)
|
|
30
|
+
expect(
|
|
31
|
+
within(getByA11yLabel(defaultSteps[currentStep])).getByTestId('StepTracker-Step-Current')
|
|
32
|
+
).toBeTruthy()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('only displays the step tracker label and no step labels on small screens', () => {
|
|
36
|
+
const { getByText, queryByText } = setup({
|
|
37
|
+
viewport: 'sm'
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const stepTrackerLabel = dictionary.en.stepTrackerLabel
|
|
41
|
+
.replace('%{stepNumber}', 1)
|
|
42
|
+
.replace('%{stepCount}', defaultSteps.length)
|
|
43
|
+
.replace('%{stepLabel}', defaultSteps[0])
|
|
44
|
+
expect(getByText(stepTrackerLabel)).toBeTruthy()
|
|
45
|
+
expect(queryByText(defaultSteps[1])).toBeFalsy()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('only displays the step labels and no step tracker label on large screens', () => {
|
|
49
|
+
const { getByText, queryByText } = setup({
|
|
50
|
+
viewport: 'lg'
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const stepTrackerLabel = dictionary.en.stepTrackerLabel
|
|
54
|
+
.replace('%{stepNumber}', 1)
|
|
55
|
+
.replace('%{stepCount}', defaultSteps.length)
|
|
56
|
+
.replace('%{stepLabel}', defaultSteps[0])
|
|
57
|
+
expect(queryByText(stepTrackerLabel)).toBeFalsy()
|
|
58
|
+
expect(getByText(defaultSteps[1])).toBeTruthy()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('displays the step tracker label if requested', () => {
|
|
62
|
+
const { getByText, queryByText } = setup({
|
|
63
|
+
current: currentStep,
|
|
64
|
+
tokens: { showStepTrackerLabel: true }
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
defaultSteps.forEach((stepTitle) => {
|
|
68
|
+
if (defaultSteps.indexOf(stepTitle) === currentStep) {
|
|
69
|
+
const stepTrackerLabel = dictionary.en.stepTrackerLabel
|
|
70
|
+
.replace('%{stepNumber}', currentStep + 1)
|
|
71
|
+
.replace('%{stepCount}', defaultSteps.length)
|
|
72
|
+
.replace('%{stepLabel}', stepTitle)
|
|
73
|
+
expect(getByText(stepTrackerLabel)).toBeTruthy()
|
|
74
|
+
} else {
|
|
75
|
+
expect(queryByText(stepTitle)).toBeFalsy()
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('displays the step names and titles if requested', () => {
|
|
81
|
+
const { getByText } = setup({ tokens: { showStepLabel: true } })
|
|
82
|
+
|
|
83
|
+
defaultSteps.forEach((stepTitle, index) => {
|
|
84
|
+
expect(getByText(dictionary.en.stepLabel.replace('%{stepNumber}', index + 1))).toBeTruthy()
|
|
85
|
+
expect(getByText(stepTitle)).toBeTruthy()
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('hides step names if requested', () => {
|
|
90
|
+
const { getByText } = setup({ tokens: { showStepLabel: true, showStepName: false } })
|
|
91
|
+
|
|
92
|
+
defaultSteps.forEach((stepTitle) => expect(getByText(stepTitle)).toBeTruthy())
|
|
93
|
+
})
|
|
94
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { fireEvent, render } from '@testing-library/react-native'
|
|
3
|
+
|
|
4
|
+
import { Tabs } from '../../src'
|
|
5
|
+
import Theme from '../../__fixtures__/Theme'
|
|
6
|
+
|
|
7
|
+
describe('Tabs', () => {
|
|
8
|
+
const items = [{ label: 'one' }, { label: 'two' }, { label: 'three' }, { label: 'four' }]
|
|
9
|
+
const linkItems = items.map((item) => ({ ...item, href: 'https://telus.com' }))
|
|
10
|
+
|
|
11
|
+
it('renders a menu', () => {
|
|
12
|
+
const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
|
|
13
|
+
expect(queryAllByA11yRole('tablist')).toHaveLength(1)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('renders menuitems by default', () => {
|
|
17
|
+
const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
|
|
18
|
+
expect(queryAllByA11yRole('tab')).toHaveLength(4)
|
|
19
|
+
expect(queryAllByA11yRole('link')).toHaveLength(0)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('renders links by if hrefs are passed', () => {
|
|
23
|
+
const { queryAllByA11yRole } = render(<Tabs items={linkItems} />, { wrapper: Theme })
|
|
24
|
+
expect(queryAllByA11yRole('tab')).toHaveLength(0)
|
|
25
|
+
expect(queryAllByA11yRole('link')).toHaveLength(4)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('is selected when pressed', () => {
|
|
29
|
+
const { queryByA11yState, getByText } = render(<Tabs items={items} />, { wrapper: Theme })
|
|
30
|
+
let selected
|
|
31
|
+
selected = queryByA11yState({ selected: true })
|
|
32
|
+
expect(selected).toBeFalsy()
|
|
33
|
+
|
|
34
|
+
fireEvent.press(getByText('two'))
|
|
35
|
+
|
|
36
|
+
selected = queryByA11yState({ selected: true })
|
|
37
|
+
expect(selected).toBeTruthy()
|
|
38
|
+
expect(selected).toHaveTextContent('two')
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -143,7 +143,7 @@ describe('Tags (uncontrolled)', () => {
|
|
|
143
143
|
</Theme>
|
|
144
144
|
)
|
|
145
145
|
|
|
146
|
-
expect(queryAllByA11yRole('
|
|
146
|
+
expect(queryAllByA11yRole('radiogroup')).toHaveLength(0)
|
|
147
147
|
expect(queryAllByA11yRole('radio')).toHaveLength(0)
|
|
148
148
|
|
|
149
149
|
const checks = queryAllByA11yRole('checkbox')
|
|
@@ -238,15 +238,14 @@ describe('Tags (controlled)', () => {
|
|
|
238
238
|
expect(handleChange).toHaveBeenCalledTimes(0)
|
|
239
239
|
|
|
240
240
|
const one = getByText('One')
|
|
241
|
-
await fireEvent
|
|
241
|
+
await fireEvent(one, 'press', { nativeEvent: 'example' })
|
|
242
242
|
expect(handleChange).toHaveBeenCalledTimes(1)
|
|
243
|
-
|
|
244
|
-
expect(handleChange.mock.calls[0][0]).toEqual(['one'])
|
|
243
|
+
expect(handleChange).toHaveBeenLastCalledWith(['one'], { nativeEvent: 'example' })
|
|
245
244
|
|
|
246
245
|
const two = getByText('Two')
|
|
247
|
-
await fireEvent
|
|
246
|
+
await fireEvent(two, 'press', { nativeEvent: 'example2' })
|
|
248
247
|
expect(handleChange).toHaveBeenCalledTimes(2)
|
|
249
|
-
expect(handleChange
|
|
248
|
+
expect(handleChange).toHaveBeenLastCalledWith(['two'], { nativeEvent: 'example2' })
|
|
250
249
|
})
|
|
251
250
|
|
|
252
251
|
it("Doesn't change its own selection if `values` is passed", async () => {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { render } from '@testing-library/react-native'
|
|
3
3
|
|
|
4
4
|
import { Platform } from 'react-native'
|
|
5
5
|
import { TextArea } from '../../src'
|
|
6
6
|
import Theme from '../../__fixtures__/Theme'
|
|
7
|
+
import { fireChange } from '../../__fixtures__/test-utils'
|
|
7
8
|
|
|
8
9
|
describe('TextArea', () => {
|
|
9
10
|
it('renders', () => {
|
|
@@ -26,7 +27,7 @@ describe('TextArea', () => {
|
|
|
26
27
|
|
|
27
28
|
expect(textarea).toHaveStyle({ height: 20 })
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
fireChange(textarea, '\n\n\n')
|
|
30
31
|
|
|
31
32
|
expect(textarea).toHaveStyle({ height: 60 })
|
|
32
33
|
})
|
|
@@ -3,6 +3,7 @@ import React from 'react'
|
|
|
3
3
|
import TextInputBase from '../../src/TextInput/TextInputBase'
|
|
4
4
|
import Viewport from '../../__fixtures__/Viewport'
|
|
5
5
|
import Theme from '../../__fixtures__/Theme'
|
|
6
|
+
import { getMockEvent, fireChange } from '../../__fixtures__/test-utils'
|
|
6
7
|
|
|
7
8
|
// eslint-disable-next-line react/prop-types
|
|
8
9
|
const Wrapper = ({ children }) => (
|
|
@@ -11,6 +12,9 @@ const Wrapper = ({ children }) => (
|
|
|
11
12
|
</Viewport>
|
|
12
13
|
)
|
|
13
14
|
|
|
15
|
+
const text = 'new value'
|
|
16
|
+
const changeEvent = getMockEvent({ text })
|
|
17
|
+
|
|
14
18
|
describe('TextInputBaseBase', () => {
|
|
15
19
|
it('triggers the interactive callbacks', () => {
|
|
16
20
|
const onFocus = jest.fn()
|
|
@@ -73,9 +77,9 @@ describe('TextInputBaseBase', () => {
|
|
|
73
77
|
const input = getByA11yLabel('Input label')
|
|
74
78
|
|
|
75
79
|
expect(onChange).not.toHaveBeenCalled()
|
|
76
|
-
|
|
80
|
+
fireChange(input, text)
|
|
77
81
|
expect(onChange).toHaveBeenCalledTimes(1)
|
|
78
|
-
expect(onChange).toHaveBeenLastCalledWith(
|
|
82
|
+
expect(onChange).toHaveBeenLastCalledWith(text, changeEvent)
|
|
79
83
|
})
|
|
80
84
|
|
|
81
85
|
it('changes value when controlled', () => {
|
|
@@ -91,9 +95,10 @@ describe('TextInputBaseBase', () => {
|
|
|
91
95
|
const input = getByA11yLabel('Input label')
|
|
92
96
|
|
|
93
97
|
expect(onChange).not.toHaveBeenCalled()
|
|
94
|
-
|
|
98
|
+
|
|
99
|
+
fireChange(input, text)
|
|
95
100
|
expect(onChange).toHaveBeenCalledTimes(1)
|
|
96
|
-
expect(onChange).toHaveBeenLastCalledWith(
|
|
101
|
+
expect(onChange).toHaveBeenLastCalledWith(text, changeEvent)
|
|
97
102
|
})
|
|
98
103
|
|
|
99
104
|
it("doesn't change value when readOnly", () => {
|
|
@@ -114,7 +119,7 @@ describe('TextInputBaseBase', () => {
|
|
|
114
119
|
const input = getByA11yLabel('Input label')
|
|
115
120
|
|
|
116
121
|
expect(onChange).not.toHaveBeenCalled()
|
|
117
|
-
|
|
122
|
+
fireChange(input, text)
|
|
118
123
|
expect(onChange).not.toHaveBeenCalled()
|
|
119
124
|
})
|
|
120
125
|
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { renderHook } from '@testing-library/react-hooks'
|
|
4
|
+
import semVerSatisfies from 'semver/functions/satisfies'
|
|
5
|
+
import ThemeProvider, { useTheme, useSetTheme } from '../../src/ThemeProvider'
|
|
6
|
+
import pkg from '../../package.json'
|
|
7
|
+
|
|
8
|
+
jest.mock('semver/functions/satisfies')
|
|
9
|
+
|
|
10
|
+
const expectedThemeTokensVersion = 'expected'
|
|
11
|
+
const actualThemeTokensVersion = 'actual'
|
|
12
|
+
pkg.dependencies['@telus-uds/system-theme-tokens'] = expectedThemeTokensVersion
|
|
13
|
+
const theme = {
|
|
14
|
+
metadata: {
|
|
15
|
+
name: 'tokens-test',
|
|
16
|
+
themeTokensVersion: actualThemeTokensVersion
|
|
17
|
+
},
|
|
18
|
+
components: {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
semVerSatisfies.mockReset()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
describe('Uninitialized ThemeProvider context', () => {
|
|
26
|
+
test('throws on useTheme', () => {
|
|
27
|
+
const { result } = renderHook(useTheme)
|
|
28
|
+
expect(() => result.current).toThrow('Theme context used outside of ThemeProvider')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('error useSetTheme hook without provider', () => {
|
|
32
|
+
const { result } = renderHook(useSetTheme)
|
|
33
|
+
expect(() => result.current).toThrow('Theme context used outside of ThemeProvider')
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
describe('ThemeProvider theme tokens version validation', () => {
|
|
38
|
+
const renderThemeHook = (hookFn) => {
|
|
39
|
+
const ThemeWrapper = ({ children }) => (
|
|
40
|
+
<ThemeProvider defaultTheme={theme}>{children}</ThemeProvider>
|
|
41
|
+
)
|
|
42
|
+
ThemeWrapper.propTypes = { children: PropTypes.node.isRequired }
|
|
43
|
+
|
|
44
|
+
return renderHook(hookFn, {
|
|
45
|
+
wrapper: ThemeWrapper
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
test('validates theme tokens version with semver', () => {
|
|
50
|
+
semVerSatisfies.mockImplementationOnce(() => true)
|
|
51
|
+
|
|
52
|
+
const { result } = renderThemeHook(useTheme)
|
|
53
|
+
|
|
54
|
+
expect(result.current).toEqual(theme)
|
|
55
|
+
expect(semVerSatisfies).toHaveBeenCalledWith(
|
|
56
|
+
actualThemeTokensVersion,
|
|
57
|
+
expectedThemeTokensVersion
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('warning if theme tokens version does not match', () => {
|
|
62
|
+
semVerSatisfies.mockImplementationOnce(() => false)
|
|
63
|
+
|
|
64
|
+
const { result } = renderThemeHook(useTheme)
|
|
65
|
+
|
|
66
|
+
expect(() => result.current).toThrow('Invalid UDS token schema version detected')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test('validates on every render', () => {
|
|
70
|
+
semVerSatisfies.mockImplementationOnce(() => true)
|
|
71
|
+
|
|
72
|
+
const { rerender } = renderThemeHook(useTheme)
|
|
73
|
+
rerender()
|
|
74
|
+
|
|
75
|
+
expect(semVerSatisfies).toHaveBeenCalledTimes(2)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -4,10 +4,13 @@ import { renderHook } from '@testing-library/react-hooks'
|
|
|
4
4
|
|
|
5
5
|
import ThemeProvider from '../../src/ThemeProvider'
|
|
6
6
|
import { useThemeTokens, useThemeTokensCallback } from '../../src/ThemeProvider/useThemeTokens'
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
import * as tokenUtils from '../../src/ThemeProvider/utils/theme-tokens'
|
|
8
|
+
|
|
9
|
+
// Mock out the function that checks the theme version
|
|
10
|
+
const validateThemeTokensVersion = jest.spyOn(tokenUtils, 'validateThemeTokensVersion')
|
|
11
|
+
validateThemeTokensVersion.mockImplementation(() => undefined)
|
|
12
|
+
|
|
13
|
+
const { doesThemeRuleApply, doesThemeConditionApply } = tokenUtils
|
|
11
14
|
|
|
12
15
|
const componentName = 'TestComponent'
|
|
13
16
|
|
|
@@ -48,7 +51,8 @@ const defaultTokens = {
|
|
|
48
51
|
|
|
49
52
|
const theme = {
|
|
50
53
|
metadata: {
|
|
51
|
-
name: 'tokens-test'
|
|
54
|
+
name: 'tokens-test',
|
|
55
|
+
themeTokensVersion: 'test-version'
|
|
52
56
|
},
|
|
53
57
|
components: {
|
|
54
58
|
[componentName]: {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import pkg from '../../../package.json'
|
|
2
|
+
import { validateThemeTokensVersion } from '../../../src/ThemeProvider/utils/theme-tokens'
|
|
3
|
+
|
|
4
|
+
function validate({ expectedVersion, actualVersion }) {
|
|
5
|
+
pkg.dependencies['@telus-uds/system-theme-tokens'] = expectedVersion
|
|
6
|
+
const theme = {
|
|
7
|
+
metadata: {
|
|
8
|
+
themeTokensVersion: actualVersion
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
validateThemeTokensVersion(theme)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe('validateThemeTokensVersion', () => {
|
|
15
|
+
test('No error on matching version', async () => {
|
|
16
|
+
const expectedVersion = '1.2.3'
|
|
17
|
+
const actualVersion = '1.2.3'
|
|
18
|
+
|
|
19
|
+
validate({ expectedVersion, actualVersion })
|
|
20
|
+
|
|
21
|
+
// No errors, no problem...
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('Throws if theme version is old', async () => {
|
|
25
|
+
const expectedVersion = '^2.3.4'
|
|
26
|
+
const actualVersion = '2.3.3'
|
|
27
|
+
|
|
28
|
+
expect(() => validate({ expectedVersion, actualVersion })).toThrow(
|
|
29
|
+
'Invalid UDS token schema version detected.'
|
|
30
|
+
)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('Throws if theme version is new', async () => {
|
|
34
|
+
const expectedVersion = '^1.2.3'
|
|
35
|
+
const actualVersion = '2.3.4'
|
|
36
|
+
|
|
37
|
+
expect(() => validate({ expectedVersion, actualVersion })).toThrow(
|
|
38
|
+
'Invalid UDS token schema version detected.'
|
|
39
|
+
)
|
|
40
|
+
})
|
|
41
|
+
})
|
|
@@ -63,9 +63,10 @@ describe('ToggleSwitch', () => {
|
|
|
63
63
|
expect(handleChange).toHaveBeenCalledTimes(0)
|
|
64
64
|
const toggleSwitch = getByA11yRole('switch')
|
|
65
65
|
expect(queryAllByA11yState(checked)).toHaveLength(0)
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
await fireEvent(toggleSwitch, 'press', { nativeEvent: 'example' })
|
|
67
68
|
expect(handleChange).toHaveBeenCalledTimes(1)
|
|
68
|
-
expect(handleChange
|
|
69
|
+
expect(handleChange).toHaveBeenLastCalledWith(true, { nativeEvent: 'example' })
|
|
69
70
|
expect(queryAllByA11yState(checked)).toHaveLength(0)
|
|
70
71
|
})
|
|
71
72
|
})
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { render } from '@testing-library/react-native'
|
|
4
|
+
import { Text, View } from 'react-native'
|
|
5
|
+
|
|
6
|
+
import { wrapStringsInText } from '../../src/utils'
|
|
7
|
+
import A11yText from '../../src/A11yText'
|
|
8
|
+
|
|
9
|
+
const TestComponent = ({ children }) => (
|
|
10
|
+
<View testID="wrapper">{wrapStringsInText(children, { testID: 'text' })}</View>
|
|
11
|
+
)
|
|
12
|
+
TestComponent.propTypes = {
|
|
13
|
+
children: PropTypes.node
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('wrapStringsInText', () => {
|
|
17
|
+
it('combines adjacent strings into one text', () => {
|
|
18
|
+
const secondString = 'Second string'
|
|
19
|
+
const { queryAllByTestId } = render(
|
|
20
|
+
<TestComponent>
|
|
21
|
+
First string
|
|
22
|
+
{secondString}
|
|
23
|
+
Third string
|
|
24
|
+
</TestComponent>
|
|
25
|
+
)
|
|
26
|
+
expect(queryAllByTestId('text')).toHaveLength(1)
|
|
27
|
+
})
|
|
28
|
+
it('combines adjacent strings and numbers into one `Text`', () => {
|
|
29
|
+
const { queryAllByTestId } = render(
|
|
30
|
+
<TestComponent>
|
|
31
|
+
First string
|
|
32
|
+
{12345}
|
|
33
|
+
Third string
|
|
34
|
+
</TestComponent>
|
|
35
|
+
)
|
|
36
|
+
expect(queryAllByTestId('text')).toHaveLength(1)
|
|
37
|
+
})
|
|
38
|
+
it('combines adjacent strings, numbers and A11yText into one `Text`', () => {
|
|
39
|
+
const { queryAllByTestId } = render(
|
|
40
|
+
<TestComponent>
|
|
41
|
+
First string
|
|
42
|
+
<A11yText text="Some inserted A11yText" />
|
|
43
|
+
Third string
|
|
44
|
+
</TestComponent>
|
|
45
|
+
)
|
|
46
|
+
expect(queryAllByTestId('text')).toHaveLength(1)
|
|
47
|
+
})
|
|
48
|
+
it('combines clusters seperated by another component into multiple `Text`s', () => {
|
|
49
|
+
const { queryAllByTestId } = render(
|
|
50
|
+
<TestComponent>
|
|
51
|
+
First string
|
|
52
|
+
{12345}
|
|
53
|
+
Third string
|
|
54
|
+
<View />
|
|
55
|
+
Fourth string
|
|
56
|
+
<A11yText text="Some inserted A11yText" />
|
|
57
|
+
Fifth string
|
|
58
|
+
<View />
|
|
59
|
+
Sixth string
|
|
60
|
+
{12345}
|
|
61
|
+
<A11yText text="Some inserted A11yText" />
|
|
62
|
+
Seventh string
|
|
63
|
+
</TestComponent>
|
|
64
|
+
)
|
|
65
|
+
expect(queryAllByTestId('text')).toHaveLength(3)
|
|
66
|
+
})
|
|
67
|
+
it('does not wrap elements that do not need wrapping', () => {
|
|
68
|
+
const { getByTestId, queryAllByTestId } = render(
|
|
69
|
+
<TestComponent>
|
|
70
|
+
Unwrapped text
|
|
71
|
+
{12345}
|
|
72
|
+
<View>
|
|
73
|
+
<Text>
|
|
74
|
+
Wrapped text inside View
|
|
75
|
+
{12345}
|
|
76
|
+
</Text>
|
|
77
|
+
</View>
|
|
78
|
+
More unwrapped text
|
|
79
|
+
{12345}
|
|
80
|
+
<Text>
|
|
81
|
+
Wrapped text separate from above unwrapped text
|
|
82
|
+
{12345}
|
|
83
|
+
</Text>
|
|
84
|
+
</TestComponent>
|
|
85
|
+
)
|
|
86
|
+
expect(queryAllByTestId('text')).toHaveLength(2)
|
|
87
|
+
expect(getByTestId('wrapper').children.map((child) => child.type)).toEqual([
|
|
88
|
+
Text,
|
|
89
|
+
View,
|
|
90
|
+
Text,
|
|
91
|
+
Text
|
|
92
|
+
])
|
|
93
|
+
})
|
|
94
|
+
it('does not wrap a singular A11yText in `Text`', () => {
|
|
95
|
+
const { queryAllByTestId } = render(
|
|
96
|
+
<TestComponent>
|
|
97
|
+
<A11yText text="Some inserted A11yText" />
|
|
98
|
+
</TestComponent>
|
|
99
|
+
)
|
|
100
|
+
expect(queryAllByTestId('text')).toHaveLength(0)
|
|
101
|
+
})
|
|
102
|
+
it('does not wrap an A11yText in `Text` if it is sandwiched by non-text', () => {
|
|
103
|
+
const { queryAllByTestId } = render(
|
|
104
|
+
<TestComponent>
|
|
105
|
+
First string
|
|
106
|
+
{12345}
|
|
107
|
+
Third string
|
|
108
|
+
<View />
|
|
109
|
+
<A11yText text="Some inserted A11yText" />
|
|
110
|
+
<View />
|
|
111
|
+
Sixth string
|
|
112
|
+
{12345}
|
|
113
|
+
<A11yText text="Some inserted A11yText" />
|
|
114
|
+
Seventh string
|
|
115
|
+
</TestComponent>
|
|
116
|
+
)
|
|
117
|
+
expect(queryAllByTestId('text')).toHaveLength(2)
|
|
118
|
+
})
|
|
119
|
+
it('does not double-wrap already wrapped `Text`', () => {
|
|
120
|
+
const { queryAllByTestId } = render(
|
|
121
|
+
<TestComponent>
|
|
122
|
+
<Text>Already wrapped</Text>
|
|
123
|
+
<Text>Also already wrapped</Text>
|
|
124
|
+
</TestComponent>
|
|
125
|
+
)
|
|
126
|
+
expect(queryAllByTestId('text')).toHaveLength(0)
|
|
127
|
+
})
|
|
128
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderHook, act } from '@testing-library/react-hooks'
|
|
2
2
|
|
|
3
|
-
import { useInputValue, useMultipleInputValues } from '../../
|
|
3
|
+
import { useInputValue, useMultipleInputValues } from '../../src/utils'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Tests for errors thrown on incorrect props usage
|
|
@@ -90,6 +90,17 @@ describe('useInputValue (uncontrolled)', () => {
|
|
|
90
90
|
expect(result.current.currentValue).toBe('some value')
|
|
91
91
|
})
|
|
92
92
|
|
|
93
|
+
it('Changes currentValue based on old value when `setValue` is passed a function', () => {
|
|
94
|
+
const { result } = renderHook(() => useInputValue({ initialValue: 1 }))
|
|
95
|
+
expect(result.current.currentValue).toBe(1)
|
|
96
|
+
|
|
97
|
+
act(() => result.current.setValue((oldValue) => oldValue + 1))
|
|
98
|
+
expect(result.current.currentValue).toBe(2)
|
|
99
|
+
|
|
100
|
+
act(() => result.current.setValue((oldValue) => oldValue + 2))
|
|
101
|
+
expect(result.current.currentValue).toBe(4)
|
|
102
|
+
})
|
|
103
|
+
|
|
93
104
|
it('Sets currentValue to initialValue if provided, which may be changed', () => {
|
|
94
105
|
const { result } = renderHook(() => useInputValue({ initialValue: 'first value' }))
|
|
95
106
|
expect(result.current.currentValue).toBe('first value')
|
|
@@ -210,6 +221,29 @@ describe('useMultipleInputValues (uncontrolled)', () => {
|
|
|
210
221
|
expect(result.current.currentValues).toEqual(['second value', 'third value'])
|
|
211
222
|
})
|
|
212
223
|
|
|
224
|
+
it('Replaces values on calling setValues', () => {
|
|
225
|
+
const { result } = renderHook(() =>
|
|
226
|
+
useMultipleInputValues({
|
|
227
|
+
initialValues: ['first value', 'second value', 'third value']
|
|
228
|
+
})
|
|
229
|
+
)
|
|
230
|
+
act(() => result.current.setValues(['new value', 'another value']))
|
|
231
|
+
expect(result.current.currentValues).toEqual(['new value', 'another value'])
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it('Replaces values based on old values on passing function to setValues', () => {
|
|
235
|
+
const { result } = renderHook(() =>
|
|
236
|
+
useMultipleInputValues({
|
|
237
|
+
initialValues: [1, 2, 3, 4]
|
|
238
|
+
})
|
|
239
|
+
)
|
|
240
|
+
act(() => result.current.setValues((oldValues) => oldValues.map((value) => value + 1)))
|
|
241
|
+
expect(result.current.currentValues).toEqual([2, 3, 4, 5])
|
|
242
|
+
|
|
243
|
+
act(() => result.current.setValues((oldValues) => oldValues.map((value) => value + 2)))
|
|
244
|
+
expect(result.current.currentValues).toEqual([4, 5, 6, 7])
|
|
245
|
+
})
|
|
246
|
+
|
|
213
247
|
it('Empties values on calling unsetValues', () => {
|
|
214
248
|
const { result } = renderHook(() =>
|
|
215
249
|
useMultipleInputValues({
|
|
@@ -237,6 +271,18 @@ describe('useInputValue (controlled)', () => {
|
|
|
237
271
|
expect(onChange.mock.calls[0][0]).toEqual('second value')
|
|
238
272
|
})
|
|
239
273
|
|
|
274
|
+
it('Calls `onChange` with result from old value when `setValue` is passed a function', () => {
|
|
275
|
+
const onChange = jest.fn((arg) => arg)
|
|
276
|
+
const { result } = renderHook(() => useInputValue({ value: 1, onChange }))
|
|
277
|
+
expect(result.current.currentValue).toBe(1)
|
|
278
|
+
expect(onChange).toHaveBeenCalledTimes(0)
|
|
279
|
+
|
|
280
|
+
act(() => result.current.setValue((oldValue) => oldValue + 1))
|
|
281
|
+
expect(result.current.currentValue).toBe(1)
|
|
282
|
+
expect(onChange).toHaveBeenCalledTimes(1)
|
|
283
|
+
expect(onChange.mock.calls[0][0]).toEqual(2)
|
|
284
|
+
})
|
|
285
|
+
|
|
240
286
|
it('Returns updated `currentValue` when non-undefined `value` prop changes', () => {
|
|
241
287
|
const onChange = () => {}
|
|
242
288
|
const { result, rerender } = renderHook(({ value }) => useInputValue({ value, onChange }), {
|
|
@@ -296,6 +342,18 @@ describe('useMultipleInputValues (controlled)', () => {
|
|
|
296
342
|
expect(onChange.mock.calls[0][0]).toEqual(['second value', 'third value'])
|
|
297
343
|
})
|
|
298
344
|
|
|
345
|
+
it('Calls `onChange` with results from old values when `setValues` is passed a function', () => {
|
|
346
|
+
const onChange = jest.fn((arg) => arg)
|
|
347
|
+
const { result } = renderHook(() => useMultipleInputValues({ values: [1, 2, 3, 4], onChange }))
|
|
348
|
+
expect(result.current.currentValues).toEqual([1, 2, 3, 4])
|
|
349
|
+
expect(onChange).toHaveBeenCalledTimes(0)
|
|
350
|
+
|
|
351
|
+
act(() => result.current.setValues((oldValues) => oldValues.map((value) => value + 1)))
|
|
352
|
+
expect(result.current.currentValues).toEqual([1, 2, 3, 4])
|
|
353
|
+
expect(onChange).toHaveBeenCalledTimes(1)
|
|
354
|
+
expect(onChange.mock.calls[0][0]).toEqual([2, 3, 4, 5])
|
|
355
|
+
})
|
|
356
|
+
|
|
299
357
|
it('Calls onChange with an empty array on calling unsetValues', () => {
|
|
300
358
|
const onChange = jest.fn((arg) => arg)
|
|
301
359
|
const { result, rerender } = renderHook(
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Platform } from 'react-native'
|
|
2
|
+
|
|
3
|
+
import { getA11yPropsFromHtmlTag, tagsToRoles, supportedTags } from '../../src'
|
|
4
|
+
|
|
5
|
+
// Note that currently all tests run as ios so only native logic can be tested here
|
|
6
|
+
// until cross-platform tests are set up. See issue:
|
|
7
|
+
// https://github.com/telus/universal-design-system/issues/319
|
|
8
|
+
|
|
9
|
+
// As a temporary measure, there are tests on web-context HTML output for Box component
|
|
10
|
+
// in @telus-uds/ds-allium which test the actual output when the tags are rendered.
|
|
11
|
+
|
|
12
|
+
// These tests will therefore just test the values returned in a native context.
|
|
13
|
+
describe('getA11yPropsFromHtmlTag', () => {
|
|
14
|
+
it.each(Object.entries(tagsToRoles))(
|
|
15
|
+
'responds to tag "%s" with accessibilityRole "%s"',
|
|
16
|
+
(tag, role) => {
|
|
17
|
+
expect(getA11yPropsFromHtmlTag(tag)).toEqual({ accessibilityRole: role })
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
it.each([
|
|
22
|
+
[1, 'h1'],
|
|
23
|
+
[2, 'h2'],
|
|
24
|
+
[3, 'h3'],
|
|
25
|
+
[4, 'h4'],
|
|
26
|
+
[5, 'h5'],
|
|
27
|
+
[6, 'h6']
|
|
28
|
+
])('returns accessibility role "header" and level "%s" for header tag "%s"', (level, tag) => {
|
|
29
|
+
expect(getA11yPropsFromHtmlTag(tag)).toEqual({
|
|
30
|
+
accessibilityRole: 'header',
|
|
31
|
+
accessibilityLevel: level
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
if (Platform.OS !== 'web') {
|
|
36
|
+
it.each(supportedTags.map((tag) => [tag]))(
|
|
37
|
+
'responds to tag "%s" and an arbitrary nativeRole with given nativeRole override',
|
|
38
|
+
(tag) => {
|
|
39
|
+
expect(getA11yPropsFromHtmlTag(tag, 'link')).toEqual({ accessibilityRole: 'link' })
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
})
|