@telus-uds/components-base 0.0.2-prerelease.1 → 0.0.2-prerelease.10
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 +120 -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 +1146 -145
- package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
- package/__tests__/Box/Box.test.jsx +81 -58
- package/__tests__/Button/ButtonBase.test.jsx +3 -32
- package/__tests__/Button/ButtonGroup.test.jsx +6 -7
- package/__tests__/Card/Card.test.jsx +63 -0
- package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
- package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
- package/__tests__/Divider/Divider.test.jsx +26 -5
- package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
- package/__tests__/Feedback/Feedback.test.jsx +42 -0
- package/__tests__/FlexGrid/Col.test.jsx +5 -0
- 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__/InputSupports/InputSupports.test.jsx +50 -0
- package/__tests__/Link/LinkBase.test.jsx +0 -14
- 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 +160 -0
- package/__tests__/Progress/Progress.test.jsx +79 -0
- package/__tests__/Radio/Radio.test.jsx +87 -0
- 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 +94 -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 +40 -0
- package/__tests__/Tags/Tags.test.jsx +327 -0
- package/__tests__/TextInput/TextArea.test.jsx +35 -0
- package/__tests__/TextInput/TextInputBase.test.jsx +125 -0
- package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
- package/__tests__/ThemeProvider/useThemeTokens.test.jsx +14 -8
- package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
- package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
- package/__tests__/Tooltip/Tooltip.test.jsx +65 -0
- package/__tests__/Tooltip/getTooltipPosition.test.js +79 -0
- package/__tests__/utils/children.test.jsx +128 -0
- package/__tests__/utils/input.test.js +59 -1
- package/__tests__/utils/useCopy.test.js +42 -0
- package/__tests__/utils/useResponsiveProp.test.jsx +202 -0
- package/__tests__/utils/useSpacingScale.test.jsx +273 -0
- package/__tests__/utils/useUniqueId.test.js +31 -0
- package/babel.config.js +18 -1
- package/jest.config.js +19 -9
- package/lib/A11yInfoProvider/index.js +54 -26
- package/lib/A11yText/index.js +36 -15
- 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 +214 -87
- package/lib/Box/index.js +13 -2
- package/lib/Button/Button.js +37 -11
- package/lib/Button/ButtonBase.js +119 -110
- package/lib/Button/ButtonGroup.js +98 -101
- package/lib/Button/ButtonLink.js +40 -14
- package/lib/Button/index.js +31 -4
- package/lib/Button/propTypes.js +32 -9
- package/lib/Card/Card.js +98 -0
- package/lib/Card/CardBase.js +78 -0
- package/lib/Card/PressableCardBase.js +137 -0
- package/lib/Card/index.js +40 -0
- 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 +80 -18
- package/lib/Divider/index.js +13 -2
- package/lib/ExpandCollapse/Accordion.js +19 -8
- package/lib/ExpandCollapse/Control.js +50 -29
- package/lib/ExpandCollapse/ExpandCollapse.js +41 -24
- package/lib/ExpandCollapse/Panel.js +77 -41
- 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 +66 -39
- package/lib/FlexGrid/Col/index.js +13 -2
- package/lib/FlexGrid/FlexGrid.js +70 -47
- package/lib/FlexGrid/Row/Row.js +47 -28
- 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 +199 -0
- package/lib/HorizontalScroll/HorizontalScrollButton.js +121 -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 +52 -47
- package/lib/Icon/IconText.js +100 -0
- package/lib/Icon/index.js +31 -3
- package/lib/IconButton/IconButton.js +135 -0
- package/lib/IconButton/index.js +13 -0
- package/lib/InputLabel/InputLabel.js +145 -0
- package/lib/InputLabel/LabelContent.js +39 -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 +56 -16
- package/lib/Link/InlinePressable.js +50 -0
- package/lib/Link/InlinePressable.native.js +101 -0
- package/lib/Link/Link.js +29 -14
- package/lib/Link/LinkBase.js +120 -147
- package/lib/Link/TextButton.js +46 -18
- package/lib/Link/index.js +39 -4
- package/lib/List/List.js +80 -0
- package/lib/List/ListItem.js +239 -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 +215 -0
- package/lib/Notification/dictionary.js +15 -0
- package/lib/Notification/index.js +13 -0
- package/lib/Pagination/PageButton.js +89 -0
- package/lib/Pagination/Pagination.js +148 -0
- package/lib/Pagination/SideButton.js +124 -0
- package/lib/Pagination/dictionary.js +25 -0
- package/lib/Pagination/index.js +13 -0
- package/lib/Pagination/usePagination.js +80 -0
- 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 +234 -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 +243 -0
- package/lib/RadioCard/RadioCardGroup.js +251 -0
- package/lib/RadioCard/index.js +21 -0
- package/lib/Search/Search.js +250 -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 +127 -0
- package/lib/Select/Select.js +341 -0
- package/lib/Select/index.js +19 -0
- package/lib/SideNav/Item.js +54 -35
- package/lib/SideNav/ItemContent.js +41 -15
- package/lib/SideNav/ItemsGroup.js +53 -34
- package/lib/SideNav/SideNav.js +94 -70
- 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 +130 -0
- package/lib/StackView/StackWrap.js +55 -0
- package/lib/StackView/StackWrap.native.js +14 -0
- package/lib/StackView/StackWrapBox.js +120 -0
- package/lib/StackView/StackWrapGap.js +71 -0
- package/lib/StackView/common.js +47 -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/Tabs.js +118 -0
- package/lib/Tabs/TabsItem.js +237 -0
- package/lib/Tabs/index.js +13 -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 +255 -0
- package/lib/TextInput/index.js +23 -0
- package/lib/TextInput/propTypes.js +42 -0
- 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 +111 -16
- package/lib/ThemeProvider/utils/index.js +31 -2
- package/lib/ThemeProvider/utils/styles.js +52 -16
- package/lib/ThemeProvider/utils/theme-tokens.js +154 -19
- package/lib/ToggleSwitch/ToggleSwitch.js +87 -93
- 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 -49
- 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 +539 -17
- 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 +134 -0
- package/lib/utils/index.js +163 -3
- 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 +62 -38
- package/lib/utils/pressability.js +120 -0
- package/lib/utils/propTypes.js +360 -109
- package/lib/utils/useCopy.js +51 -0
- package/lib/utils/useHash.js +52 -0
- package/lib/utils/useHash.native.js +15 -0
- package/lib/utils/useResponsiveProp.js +59 -0
- package/lib/utils/useSpacingScale.js +135 -0
- package/lib/utils/useUniqueId.js +21 -0
- package/package.json +15 -14
- package/release-context.json +4 -4
- package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +0 -0
- package/src/Box/Box.jsx +180 -78
- package/src/Button/Button.jsx +9 -5
- package/src/Button/ButtonBase.jsx +74 -87
- package/src/Button/ButtonGroup.jsx +26 -43
- package/src/Button/ButtonLink.jsx +14 -4
- package/src/Button/propTypes.js +12 -2
- package/src/Card/Card.jsx +75 -0
- package/src/Card/CardBase.jsx +57 -0
- package/src/Card/PressableCardBase.jsx +112 -0
- package/src/Card/index.js +6 -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 +3 -4
- package/src/ExpandCollapse/Panel.jsx +3 -3
- 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/FlexGrid/Col/Col.jsx +4 -2
- package/src/HorizontalScroll/HorizontalScroll.jsx +165 -0
- package/src/HorizontalScroll/HorizontalScrollButton.jsx +108 -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 +23 -27
- package/src/Icon/IconText.jsx +63 -0
- package/src/Icon/index.js +3 -2
- package/src/IconButton/IconButton.jsx +107 -0
- package/src/IconButton/index.js +3 -0
- package/src/InputLabel/InputLabel.jsx +124 -0
- package/src/InputLabel/LabelContent.jsx +23 -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 +184 -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 +161 -0
- package/src/Notification/dictionary.js +8 -0
- package/src/Notification/index.js +3 -0
- package/src/Pagination/PageButton.jsx +70 -0
- package/src/Pagination/Pagination.jsx +135 -0
- package/src/Pagination/SideButton.jsx +82 -0
- package/src/Pagination/dictionary.js +18 -0
- package/src/Pagination/index.js +3 -0
- package/src/Pagination/usePagination.js +69 -0
- 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 +199 -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 +215 -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 +108 -0
- package/src/Select/Select.jsx +286 -0
- package/src/Select/index.js +8 -0
- package/src/SideNav/Item.jsx +5 -5
- package/src/SideNav/ItemsGroup.jsx +11 -13
- package/src/SideNav/SideNav.jsx +2 -1
- 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 +113 -0
- package/src/StackView/StackWrap.jsx +41 -0
- package/src/StackView/StackWrap.native.jsx +4 -0
- package/src/StackView/StackWrapBox.jsx +102 -0
- package/src/StackView/StackWrapGap.jsx +49 -0
- package/src/StackView/common.jsx +29 -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/Tabs.jsx +92 -0
- package/src/Tabs/TabsItem.jsx +205 -0
- package/src/Tabs/index.js +3 -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 +211 -0
- package/src/TextInput/index.js +4 -0
- package/src/TextInput/propTypes.js +29 -0
- package/src/ThemeProvider/ThemeProvider.jsx +11 -7
- package/src/ThemeProvider/useSetTheme.js +4 -0
- package/src/ThemeProvider/useThemeTokens.js +85 -7
- package/src/ThemeProvider/utils/styles.js +18 -5
- package/src/ThemeProvider/utils/theme-tokens.js +106 -8
- package/src/ToggleSwitch/ToggleSwitch.jsx +25 -46
- 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 +38 -1
- package/src/utils/a11y/index.js +1 -0
- package/src/utils/a11y/textSize.js +30 -0
- package/src/utils/children.jsx +119 -0
- package/src/utils/index.js +11 -0
- 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 +38 -26
- package/src/utils/pressability.js +96 -0
- package/src/utils/propTypes.js +298 -66
- package/src/utils/useCopy.js +39 -0
- package/src/utils/useHash.js +39 -0
- package/src/utils/useHash.native.js +6 -0
- package/src/utils/useResponsiveProp.js +50 -0
- package/src/utils/useSpacingScale.js +108 -0
- 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 +46 -17
- 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 +62 -0
- 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 +35 -7
- package/stories/IconButton/IconButton.stories.jsx +50 -0
- package/stories/InputLabel/InputLabel.stories.jsx +42 -0
- package/stories/Link/ChevronLink.stories.jsx +20 -4
- package/stories/Link/Link.stories.jsx +51 -20
- package/stories/Link/TextButton.stories.jsx +24 -3
- 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 +64 -0
- 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 +148 -14
- package/__fixtures__/accessible.icon.svg +0 -6
- 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 -57
- package/lib/config/svgr-icons-web.js +0 -9
- package/lib/config/svgr-icons.js +0 -52
- package/src/config/svgr-icons-web.js +0 -11
- package/src/config/svgr-icons.js +0 -46
|
@@ -0,0 +1,286 @@
|
|
|
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
|
+
/**
|
|
236
|
+
* Initial value for the uncontrolled version.
|
|
237
|
+
*/
|
|
238
|
+
initialValue: PropTypes.string,
|
|
239
|
+
/**
|
|
240
|
+
* Current value to be set as selected.
|
|
241
|
+
*/
|
|
242
|
+
value: PropTypes.string,
|
|
243
|
+
/**
|
|
244
|
+
* Callback to be called when the value changes.
|
|
245
|
+
*/
|
|
246
|
+
onChange: PropTypes.func,
|
|
247
|
+
/**
|
|
248
|
+
* An array of items or item groups to be used as options.
|
|
249
|
+
*/
|
|
250
|
+
children: componentPropType(['Item', 'Group']),
|
|
251
|
+
/**
|
|
252
|
+
* Whether the select is disabled.
|
|
253
|
+
*/
|
|
254
|
+
inactive: PropTypes.bool,
|
|
255
|
+
/**
|
|
256
|
+
* Whether the select is read-only.
|
|
257
|
+
*/
|
|
258
|
+
readOnly: PropTypes.bool,
|
|
259
|
+
/**
|
|
260
|
+
* A placeholder to provide instructions (such as "Please select...")
|
|
261
|
+
* as an unselectable option
|
|
262
|
+
*/
|
|
263
|
+
placeholder: PropTypes.string,
|
|
264
|
+
/**
|
|
265
|
+
* Select tokens.
|
|
266
|
+
*/
|
|
267
|
+
tokens: getTokensPropType('Select'),
|
|
268
|
+
/**
|
|
269
|
+
* Select variant.
|
|
270
|
+
*/
|
|
271
|
+
variant: variantProp.propType,
|
|
272
|
+
/**
|
|
273
|
+
* Dedicated ID for testing.
|
|
274
|
+
*/
|
|
275
|
+
testID: PropTypes.string
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export default Select
|
|
279
|
+
|
|
280
|
+
const staticStyles = StyleSheet.create({
|
|
281
|
+
iconContainer: {
|
|
282
|
+
position: 'absolute',
|
|
283
|
+
right: 0,
|
|
284
|
+
bottom: 0
|
|
285
|
+
}
|
|
286
|
+
})
|
package/src/SideNav/Item.jsx
CHANGED
|
@@ -58,18 +58,18 @@ const Item = ({
|
|
|
58
58
|
accessibilityRole,
|
|
59
59
|
href,
|
|
60
60
|
onPress: handlePress,
|
|
61
|
-
|
|
61
|
+
hrefAttrs,
|
|
62
62
|
...rest
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
-
const getTokens = useThemeTokensCallback('SideNavItem')
|
|
65
|
+
const getTokens = useThemeTokensCallback('SideNavItem', tokens, variant)
|
|
66
66
|
const getAppearanceState = ({ hovered }) => ({
|
|
67
67
|
hover: hovered,
|
|
68
68
|
active: isActive,
|
|
69
69
|
expanded: isExpanded
|
|
70
70
|
})
|
|
71
71
|
const getPressableStyle = (pressableState) =>
|
|
72
|
-
selectItemStyles(getTokens(
|
|
72
|
+
selectItemStyles(getTokens(getAppearanceState(pressableState)))
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
75
|
<Pressable
|
|
@@ -79,7 +79,7 @@ const Item = ({
|
|
|
79
79
|
testID={testID}
|
|
80
80
|
>
|
|
81
81
|
{(pressableState) => {
|
|
82
|
-
const themeTokens = getTokens(
|
|
82
|
+
const themeTokens = getTokens(getAppearanceState(pressableState))
|
|
83
83
|
return <ItemContent tokens={themeTokens}>{children}</ItemContent>
|
|
84
84
|
}}
|
|
85
85
|
</Pressable>
|
|
@@ -105,7 +105,7 @@ Item.propTypes = {
|
|
|
105
105
|
href: PropTypes.string,
|
|
106
106
|
/**
|
|
107
107
|
* On Web if href is passed, React Native Web maps this object's props to
|
|
108
|
-
* `rel`, `target` and
|
|
108
|
+
* `rel`, `target` and `download` attrs.
|
|
109
109
|
*/
|
|
110
110
|
hrefAttrs: PropTypes.shape(hrefAttrsProp.types),
|
|
111
111
|
/**
|
|
@@ -28,25 +28,23 @@ const ItemsGroup = ({
|
|
|
28
28
|
onToggle
|
|
29
29
|
}) => {
|
|
30
30
|
// A SideNav control uses the same style and theme as SideNavItem, with a 'parent' variant,
|
|
31
|
-
// plus control-specific tokens from the SideNavItemsGroup theme.
|
|
31
|
+
// plus control-specific tokens from the SideNavItemsGroup theme (e.g. open/close icon, etc).
|
|
32
32
|
const getAppearance = (appearance) => ({ ...variant, ...appearance, active: isActive })
|
|
33
33
|
const getItemAppearance = (appearance) => ({ ...getAppearance(appearance), type: 'parent' })
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const panelTokensGetterProp = (appearance) =>
|
|
39
|
-
selectTokens('ExpandCollapsePanel', getGroupTokens(tokens, getAppearance(appearance)))
|
|
35
|
+
const getGroupTokens = useThemeTokensCallback('SideNavItemsGroup', tokens, variant)
|
|
36
|
+
const getPanelTokens = (appearance) =>
|
|
37
|
+
selectTokens('ExpandCollapsePanel', getGroupTokens(getAppearance(appearance)))
|
|
40
38
|
|
|
41
|
-
const getItemTokens = useThemeTokensCallback('SideNavItem')
|
|
42
|
-
const
|
|
39
|
+
const getItemTokens = useThemeTokensCallback('SideNavItem', itemTokens, variant)
|
|
40
|
+
const getControlTokens = (appearance) =>
|
|
43
41
|
selectTokens('ExpandCollapseControl', {
|
|
44
|
-
...getItemTokens(
|
|
45
|
-
...getGroupTokens(
|
|
42
|
+
...getItemTokens(getItemAppearance(appearance)), // main style from SideNavItem
|
|
43
|
+
...getGroupTokens(getAppearance(appearance)) // control-specific tokens like icon etc
|
|
46
44
|
})
|
|
47
45
|
|
|
48
46
|
const controlContent = (controlState) => {
|
|
49
|
-
const currentItemTokens = getItemTokens(
|
|
47
|
+
const currentItemTokens = getItemTokens(getItemAppearance(controlState))
|
|
50
48
|
return <ItemContent tokens={currentItemTokens}>{label}</ItemContent>
|
|
51
49
|
}
|
|
52
50
|
|
|
@@ -55,8 +53,8 @@ const ItemsGroup = ({
|
|
|
55
53
|
openIds={openGroups}
|
|
56
54
|
panelId={groupId}
|
|
57
55
|
onToggle={onToggle}
|
|
58
|
-
tokens={
|
|
59
|
-
controlTokens={
|
|
56
|
+
tokens={getPanelTokens}
|
|
57
|
+
controlTokens={getControlTokens}
|
|
60
58
|
control={controlContent}
|
|
61
59
|
accessibilityState={{ active: isActive }} // ExpandCollapse.Panel handles expanded state
|
|
62
60
|
>
|
package/src/SideNav/SideNav.jsx
CHANGED
|
@@ -62,6 +62,7 @@ const SideNav = ({ children, variant = {}, tokens, accordion = true, itemTokens,
|
|
|
62
62
|
if (child.type === ItemsGroup) {
|
|
63
63
|
const { groupId = `group-${index}` } = child.props
|
|
64
64
|
const isGroupActive = active.itemId !== undefined && active.groupId === groupId
|
|
65
|
+
const handleToggle = (event) => onToggle(groupId, event)
|
|
65
66
|
return (
|
|
66
67
|
<ItemsGroup
|
|
67
68
|
{...child.props}
|
|
@@ -72,7 +73,7 @@ const SideNav = ({ children, variant = {}, tokens, accordion = true, itemTokens,
|
|
|
72
73
|
itemTokens={itemTokens}
|
|
73
74
|
openGroups={openIds}
|
|
74
75
|
isActive={isGroupActive}
|
|
75
|
-
onToggle={
|
|
76
|
+
onToggle={handleToggle}
|
|
76
77
|
>
|
|
77
78
|
{React.Children.map(child.props.children, (item, itemIndex) =>
|
|
78
79
|
renderItem(item, itemIndex, groupId)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Animated, Platform } from 'react-native'
|
|
3
|
+
import propTypes from 'prop-types'
|
|
4
|
+
import StackView from '../StackView'
|
|
5
|
+
import { useThemeTokens } from '../ThemeProvider'
|
|
6
|
+
import { getTokensPropType, useSpacingScale, variantProp } from '../utils'
|
|
7
|
+
import useSkeletonNativeAnimation from './useSkeletonNativeAnimation'
|
|
8
|
+
import skeletonWebAnimation from './skeletonWebAnimation'
|
|
9
|
+
|
|
10
|
+
const selectSkeletonStyles = ({ color, radius, fadeAnimation }) => ({
|
|
11
|
+
backgroundColor: color,
|
|
12
|
+
borderRadius: radius,
|
|
13
|
+
...fadeAnimation
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const selectLineStyles = ({ skeletonHeight, lineWidth }) => ({
|
|
17
|
+
width: lineWidth,
|
|
18
|
+
height: skeletonHeight
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const selectShapeStyles = ({ skeletonHeight }) => ({
|
|
22
|
+
height: skeletonHeight,
|
|
23
|
+
width: skeletonHeight
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const selectSquareStyles = ({ radius }) => ({
|
|
27
|
+
borderRadius: radius
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const Skeleton = ({ tokens, variant, size, characters, lines, shape = 'line' }) => {
|
|
31
|
+
const themeTokens = useThemeTokens('Skeleton', tokens, variant)
|
|
32
|
+
const skeletonHeight = useSpacingScale(size || themeTokens.size)
|
|
33
|
+
const nativeAnimation = useSkeletonNativeAnimation()
|
|
34
|
+
|
|
35
|
+
const getAnimationBaseOnPlatform = () => {
|
|
36
|
+
if (Platform.OS !== 'web') {
|
|
37
|
+
return nativeAnimation
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return skeletonWebAnimation
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const getLineWidth = () => {
|
|
44
|
+
if (characters) {
|
|
45
|
+
return characters * themeTokens.baseWidth
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return themeTokens.characters * themeTokens.baseWidth
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const getStyledBasedOnShape = () => {
|
|
52
|
+
if (shape === 'circle') {
|
|
53
|
+
return selectShapeStyles({ skeletonHeight })
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (shape === 'box') {
|
|
57
|
+
return [
|
|
58
|
+
selectShapeStyles({ skeletonHeight }),
|
|
59
|
+
selectSquareStyles({ radius: themeTokens.squareRadius })
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return selectLineStyles({ skeletonHeight, lineWidth: getLineWidth() })
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const renderSkeleton = (index = 0) => (
|
|
67
|
+
<Animated.View
|
|
68
|
+
testID="skeleton"
|
|
69
|
+
key={`skeleton-${index + 1}`}
|
|
70
|
+
style={[
|
|
71
|
+
selectSkeletonStyles({ ...themeTokens, fadeAnimation: getAnimationBaseOnPlatform() }),
|
|
72
|
+
getStyledBasedOnShape()
|
|
73
|
+
]}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
if (lines) {
|
|
78
|
+
const arrayOfSkeletons = [...Array(lines)]
|
|
79
|
+
return (
|
|
80
|
+
<StackView space={themeTokens.spaceBetweenLines}>
|
|
81
|
+
{arrayOfSkeletons.map((_, index) => renderSkeleton(index))}
|
|
82
|
+
</StackView>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return renderSkeleton()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Skeleton.propTypes = {
|
|
90
|
+
tokens: getTokensPropType('Skeleton'),
|
|
91
|
+
variant: variantProp.propType,
|
|
92
|
+
size: propTypes.number,
|
|
93
|
+
characters: propTypes.number,
|
|
94
|
+
lines: propTypes.number,
|
|
95
|
+
shape: propTypes.oneOf(['line', 'circle', 'box'])
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default Skeleton
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ANIMATION_DURATION, DEFAULT_OPACITY, OPACITY_STOP } from './skeleton.constant'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
animationDuration: `${ANIMATION_DURATION}ms`,
|
|
5
|
+
animationTimingFunction: 'ease-in-out',
|
|
6
|
+
animationDelay: '0.5s',
|
|
7
|
+
animationIterationCount: 'infinite',
|
|
8
|
+
animationKeyframes: {
|
|
9
|
+
'0%': { opacity: DEFAULT_OPACITY },
|
|
10
|
+
'50%': { opacity: OPACITY_STOP },
|
|
11
|
+
'100%': { opacity: DEFAULT_OPACITY }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
import { Animated } from 'react-native'
|
|
3
|
+
import { ANIMATION_DURATION, DEFAULT_OPACITY, OPACITY_STOP } from './skeleton.constant'
|
|
4
|
+
|
|
5
|
+
const useSkeletonNativeAnimation = () => {
|
|
6
|
+
const fadeAnimation = useRef(new Animated.Value(DEFAULT_OPACITY)).current
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const fade = Animated.sequence([
|
|
10
|
+
Animated.timing(fadeAnimation, {
|
|
11
|
+
toValue: OPACITY_STOP,
|
|
12
|
+
duration: ANIMATION_DURATION,
|
|
13
|
+
useNativeDriver: true
|
|
14
|
+
}),
|
|
15
|
+
Animated.timing(fadeAnimation, {
|
|
16
|
+
toValue: DEFAULT_OPACITY,
|
|
17
|
+
duration: ANIMATION_DURATION,
|
|
18
|
+
useNativeDriver: true
|
|
19
|
+
})
|
|
20
|
+
])
|
|
21
|
+
Animated.loop(fade).start()
|
|
22
|
+
}, [fadeAnimation])
|
|
23
|
+
|
|
24
|
+
return { opacity: fadeAnimation }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default useSkeletonNativeAnimation
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { StyleSheet, View } from 'react-native'
|
|
4
|
+
|
|
5
|
+
import { useSpacingScale, spacingProps } from '../utils'
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('../utils/propTypes.js').SpacingValue} SpacingValue
|
|
8
|
+
* @typedef {import('../utils/propTypes.js').SpacingObject} SpacingObject
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const selectSizeStyle = (size, direction) => ({
|
|
12
|
+
// Only apply space in one direction at a time, else large spacers will increase the
|
|
13
|
+
// 'across' size of the parent and mess up siblings with styles like `alignItems: stretch`.
|
|
14
|
+
[direction === 'row' ? 'width' : 'height']: size
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An empty element used to create a gap between components that is sized according to the theme spacing scale,
|
|
19
|
+
* passing its `space` prop ({@link SpacingValue}) to `useSpacingScale`.
|
|
20
|
+
*
|
|
21
|
+
* ## Simple spacing
|
|
22
|
+
*
|
|
23
|
+
* For most simple uses, pass a number to Spacer's `space` prop referring to an index in the theme's
|
|
24
|
+
* spacing scale. For example, for a spacer of the theme's smallest non-zero spacing size:
|
|
25
|
+
*
|
|
26
|
+
* ```jsx
|
|
27
|
+
* <Spacer space={1} />
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* ## Responsive spacing
|
|
31
|
+
*
|
|
32
|
+
* Different spacing scale sizes may be chosen for different viewports by passing `space` a {@link SpacingObject}
|
|
33
|
+
* using keys for the viewports at and above which certain spacing indexes should apply.
|
|
34
|
+
*
|
|
35
|
+
* This can be useful when a Spacer is inside a layout with a shape that changes between viewports.
|
|
36
|
+
*
|
|
37
|
+
* For example, a spacer might need no width below 'md' viewport because the items it separates will be on separate lines,
|
|
38
|
+
* but may need a visible size above that viewport, and a wider size at the highest viewport:
|
|
39
|
+
*
|
|
40
|
+
* ```jsx
|
|
41
|
+
* <Spacer space={{ xs: 0, md: 2, xl: 3 }} />
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Note that themes may also define viewport-specific behaviour for indexes on the spacing scale. These viewport
|
|
45
|
+
* props should only be used where necessary to achieve a certain responsive layoutm and shouldn't be used to replace
|
|
46
|
+
* or deviate from responsive spacing behaviour in a theme that is intended to apply universally.
|
|
47
|
+
*
|
|
48
|
+
* ## More options
|
|
49
|
+
*
|
|
50
|
+
* See `useSpacingScale` hook for more options that may be used with the `space` prop.
|
|
51
|
+
*
|
|
52
|
+
* ## Accessibility
|
|
53
|
+
*
|
|
54
|
+
* Spacer has no content and is ignored by tools such as screen readers. Use `Divider` for
|
|
55
|
+
* separations between elements that may be treated as semantically meaningful on web.
|
|
56
|
+
*/
|
|
57
|
+
const Spacer = ({ space = 1, direction = 'column', testID }) => {
|
|
58
|
+
const size = useSpacingScale(space)
|
|
59
|
+
const sizeStyle = selectSizeStyle(size, direction)
|
|
60
|
+
return <View testID={testID} style={[staticStyles.stretch, sizeStyle]} />
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Spacer.propTypes = {
|
|
64
|
+
/**
|
|
65
|
+
* The size of the spacer according to the theme's spacing scale.
|
|
66
|
+
* Either a number corresponding to a position on the theme's spacing scale (1 is smallest, 2 is second smallest, etc),
|
|
67
|
+
* or, a SpacingObject with viewport keys and options (see `useSpacingScale` for details).
|
|
68
|
+
*/
|
|
69
|
+
space: spacingProps.types.spacingValue,
|
|
70
|
+
/**
|
|
71
|
+
* The spacer applies space in only one direction, which is controlled by the `direction` prop:
|
|
72
|
+
*
|
|
73
|
+
* - `'column'` (default) applies space vertically; has a fixed height and not width.
|
|
74
|
+
* - `'row'` applies space horizontally; has a fixed width and not height.
|
|
75
|
+
*/
|
|
76
|
+
direction: PropTypes.oneOf(['column', 'row']),
|
|
77
|
+
/**
|
|
78
|
+
* @ignore
|
|
79
|
+
* In tests, the only way to select Spacers is with testID prop and getByTestId, since they have no content,
|
|
80
|
+
* no accessibility role, and there is no equivalent of nextSibling in React Native Testing Library.
|
|
81
|
+
*/
|
|
82
|
+
testID: PropTypes.string
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const staticStyles = StyleSheet.create({
|
|
86
|
+
stretch: {
|
|
87
|
+
alignSelf: 'stretch'
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
export default Spacer
|