@telus-uds/components-base 0.0.2-prerelease.7 → 0.0.2-prerelease.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ultra.cache.json +1 -1
- package/CHANGELOG.md +27 -0
- package/__fixtures__/Accessible.js +33 -0
- package/__fixtures__/Accessible.native.js +32 -0
- package/__fixtures__/testTheme.js +429 -29
- package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
- package/__tests__/Button/ButtonGroup.test.jsx +2 -2
- package/__tests__/Checkbox/CheckboxGroup.test.jsx +247 -0
- package/__tests__/Icon/Icon.test.jsx +3 -3
- 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/RadioGroup.test.jsx +221 -0
- package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
- package/__tests__/RadioCard/RadioCardGroup.test.jsx +247 -0
- package/__tests__/Search/Search.test.jsx +72 -0
- package/__tests__/Skeleton/Skeleton.test.jsx +1 -1
- package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
- package/__tests__/Tabs/Tabs.test.jsx +200 -0
- package/__tests__/Tags/Tags.test.jsx +1 -1
- package/__tests__/utils/input.test.js +58 -0
- package/__tests__/utils/useCopy.test.js +14 -3
- package/babel.config.js +20 -0
- package/jest.config.js +1 -1
- package/lib/A11yInfoProvider/index.js +54 -26
- package/lib/A11yText/index.js +37 -14
- package/lib/ActivityIndicator/Spinner.js +78 -0
- package/lib/ActivityIndicator/Spinner.native.js +121 -87
- package/lib/ActivityIndicator/index.js +28 -12
- package/lib/ActivityIndicator/shared.js +27 -12
- package/lib/BaseProvider/index.js +34 -11
- package/lib/Box/Box.js +54 -31
- package/lib/Box/index.js +13 -2
- package/lib/Button/Button.js +32 -11
- package/lib/Button/ButtonBase.js +85 -78
- package/lib/Button/ButtonGroup.js +94 -70
- package/lib/Button/ButtonLink.js +38 -15
- package/lib/Button/index.js +31 -4
- package/lib/Button/propTypes.js +32 -9
- package/lib/Card/Card.js +36 -41
- package/lib/Card/CardBase.js +78 -0
- package/lib/Card/PressableCardBase.js +137 -0
- package/lib/Card/index.js +40 -2
- package/lib/Checkbox/Checkbox.js +139 -103
- package/lib/Checkbox/CheckboxGroup.js +231 -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 +50 -24
- package/lib/Divider/index.js +13 -2
- package/lib/ExpandCollapse/Accordion.js +20 -7
- package/lib/ExpandCollapse/Control.js +50 -27
- package/lib/ExpandCollapse/ExpandCollapse.js +41 -24
- package/lib/ExpandCollapse/Panel.js +75 -37
- package/lib/ExpandCollapse/index.js +25 -7
- package/lib/Feedback/Feedback.js +69 -40
- package/lib/Feedback/index.js +13 -2
- package/lib/Fieldset/Fieldset.js +160 -0
- package/lib/Fieldset/FieldsetContainer.js +41 -0
- package/lib/Fieldset/FieldsetContainer.native.js +33 -0
- package/lib/Fieldset/Legend.js +33 -0
- package/lib/Fieldset/Legend.native.js +43 -0
- package/lib/Fieldset/cssReset.js +21 -0
- package/lib/Fieldset/index.js +13 -0
- package/lib/FlexGrid/Col/Col.js +67 -38
- package/lib/FlexGrid/Col/index.js +13 -2
- package/lib/FlexGrid/FlexGrid.js +70 -45
- package/lib/FlexGrid/Row/Row.js +48 -27
- package/lib/FlexGrid/Row/index.js +13 -2
- package/lib/FlexGrid/helpers/index.js +9 -1
- package/lib/FlexGrid/index.js +13 -2
- package/lib/FlexGrid/providers/GutterContext.js +15 -3
- package/lib/Icon/Icon.js +46 -44
- package/lib/Icon/IconText.js +49 -21
- package/lib/Icon/index.js +31 -4
- package/lib/InputLabel/InputLabel.js +70 -36
- package/lib/InputLabel/LabelContent.js +31 -0
- package/lib/InputLabel/LabelContent.native.js +9 -1
- package/lib/InputLabel/index.js +13 -2
- package/lib/InputSupports/InputSupports.js +62 -48
- 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 +33 -16
- package/lib/Link/InlinePressable.js +50 -0
- package/lib/Link/InlinePressable.native.js +34 -11
- package/lib/Link/Link.js +25 -9
- package/lib/Link/LinkBase.js +87 -57
- package/lib/Link/TextButton.js +32 -13
- package/lib/Link/index.js +39 -5
- package/lib/List/List.js +51 -23
- package/lib/List/ListItem.js +70 -40
- package/lib/List/index.js +13 -2
- package/lib/Modal/Modal.js +226 -0
- package/lib/Modal/dictionary.js +16 -0
- package/lib/Modal/index.js +13 -0
- package/lib/Notification/Notification.js +200 -0
- package/lib/Notification/dictionary.js +15 -0
- package/lib/Notification/index.js +13 -0
- package/lib/Pagination/PageButton.js +47 -25
- package/lib/Pagination/Pagination.js +70 -40
- package/lib/Pagination/SideButton.js +63 -37
- package/lib/Pagination/dictionary.js +9 -2
- package/lib/Pagination/index.js +13 -2
- package/lib/Pagination/usePagination.js +12 -2
- package/lib/Progress/Progress.js +99 -0
- package/lib/Progress/ProgressBar.js +146 -0
- package/lib/Progress/ProgressBarBackground.js +57 -0
- package/lib/Progress/index.js +16 -0
- package/lib/Radio/Radio.js +110 -109
- package/lib/Radio/RadioButton.js +141 -0
- package/lib/Radio/RadioGroup.js +233 -0
- package/lib/Radio/RadioInput.js +76 -0
- package/lib/Radio/RadioInput.native.js +9 -1
- package/lib/Radio/index.js +21 -2
- package/lib/RadioCard/RadioCard.js +240 -0
- package/lib/RadioCard/RadioCardGroup.js +251 -0
- package/lib/RadioCard/index.js +21 -0
- package/lib/Search/Search.js +243 -0
- package/lib/Search/dictionary.js +19 -0
- package/lib/Search/index.js +13 -0
- package/lib/Select/Group.js +33 -0
- package/lib/Select/Group.native.js +16 -5
- package/lib/Select/Item.js +29 -0
- package/lib/Select/Item.native.js +14 -4
- package/lib/Select/Picker.js +79 -0
- package/lib/Select/Picker.native.js +52 -24
- package/lib/Select/Select.js +110 -82
- package/lib/Select/index.js +19 -6
- package/lib/SideNav/Item.js +54 -33
- package/lib/SideNav/ItemContent.js +41 -15
- package/lib/SideNav/ItemsGroup.js +46 -27
- package/lib/SideNav/SideNav.js +92 -69
- package/lib/SideNav/index.js +15 -1
- package/lib/Skeleton/Skeleton.js +55 -37
- 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 +31 -12
- package/lib/Spacer/index.js +13 -2
- package/lib/StackView/StackView.js +49 -27
- package/lib/StackView/StackWrap.js +33 -10
- package/lib/StackView/StackWrap.native.js +13 -2
- package/lib/StackView/StackWrapBox.js +46 -24
- package/lib/StackView/StackWrapGap.js +43 -22
- package/lib/StackView/common.js +19 -4
- package/lib/StackView/getStackedContent.js +49 -19
- package/lib/StackView/index.js +29 -5
- package/lib/StepTracker/Step.js +245 -0
- package/lib/StepTracker/StepTracker.js +197 -0
- package/lib/StepTracker/dictionary.js +17 -0
- package/lib/StepTracker/index.js +13 -0
- package/lib/Tabs/HorizontalScroll.js +199 -0
- package/lib/Tabs/ScrollViewEnd.js +66 -0
- package/lib/Tabs/ScrollViewEnd.native.js +41 -0
- package/lib/Tabs/Tabs.js +117 -0
- package/lib/Tabs/TabsItem.js +234 -0
- package/lib/Tabs/TabsScrollButton.js +121 -0
- package/lib/Tabs/dictionary.js +18 -0
- package/lib/Tabs/index.js +13 -0
- package/lib/Tabs/itemPositions.js +128 -0
- package/lib/Tags/Tags.js +130 -97
- package/lib/Tags/index.js +13 -2
- package/lib/TextInput/TextArea.js +51 -24
- package/lib/TextInput/TextInput.js +40 -19
- package/lib/TextInput/TextInputBase.js +78 -55
- package/lib/TextInput/index.js +23 -3
- package/lib/TextInput/propTypes.js +18 -7
- package/lib/ThemeProvider/ThemeProvider.js +38 -14
- package/lib/ThemeProvider/index.js +61 -6
- package/lib/ThemeProvider/useSetTheme.js +14 -5
- package/lib/ThemeProvider/useTheme.js +13 -4
- package/lib/ThemeProvider/useThemeTokens.js +32 -16
- package/lib/ThemeProvider/utils/index.js +31 -2
- package/lib/ThemeProvider/utils/styles.js +52 -16
- package/lib/ThemeProvider/utils/theme-tokens.js +94 -16
- package/lib/ToggleSwitch/ToggleSwitch.js +75 -51
- package/lib/ToggleSwitch/index.js +13 -2
- package/lib/Tooltip/{Backdrop.web.js → Backdrop.js} +22 -18
- package/lib/Tooltip/Backdrop.native.js +39 -15
- package/lib/Tooltip/Tooltip.js +112 -70
- 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 +57 -27
- 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 +509 -33
- package/lib/utils/a11y/index.js +18 -1
- package/lib/utils/a11y/textSize.js +23 -7
- package/lib/utils/animation/index.js +15 -2
- package/lib/utils/animation/useVerticalExpandAnimation.js +28 -11
- package/lib/utils/children.js +87 -0
- package/lib/utils/index.js +163 -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 +51 -33
- package/lib/utils/pressability.js +38 -10
- package/lib/utils/propTypes.js +217 -125
- package/lib/utils/useCopy.js +40 -5
- package/lib/utils/useHash.js +48 -0
- package/lib/utils/useHash.native.js +15 -0
- package/lib/utils/useResponsiveProp.js +21 -9
- package/lib/utils/useSpacingScale.js +21 -9
- package/lib/utils/useUniqueId.js +13 -4
- package/package.json +7 -6
- package/release-context.json +4 -4
- package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +0 -0
- package/src/Box/Box.jsx +11 -4
- package/src/Button/Button.jsx +3 -2
- package/src/Button/ButtonBase.jsx +27 -36
- package/src/Button/ButtonGroup.jsx +2 -2
- package/src/Button/ButtonLink.jsx +3 -2
- package/src/Button/propTypes.js +12 -2
- package/src/Card/Card.jsx +4 -30
- package/src/Card/CardBase.jsx +57 -0
- package/src/Card/PressableCardBase.jsx +112 -0
- package/src/Card/index.js +3 -0
- package/src/Checkbox/Checkbox.jsx +10 -11
- package/src/Checkbox/CheckboxGroup.jsx +196 -0
- package/src/Checkbox/{CheckboxInput.web.jsx → CheckboxInput.jsx} +0 -0
- package/src/Checkbox/index.js +2 -0
- package/src/ExpandCollapse/Control.jsx +1 -1
- package/src/Feedback/Feedback.jsx +1 -1
- package/src/Fieldset/Fieldset.jsx +129 -0
- package/src/Fieldset/FieldsetContainer.jsx +22 -0
- package/src/Fieldset/FieldsetContainer.native.jsx +16 -0
- package/src/Fieldset/Legend.jsx +16 -0
- package/src/Fieldset/Legend.native.jsx +22 -0
- package/src/Fieldset/cssReset.js +14 -0
- package/src/Fieldset/index.js +3 -0
- package/src/Icon/Icon.jsx +14 -23
- package/src/Icon/IconText.jsx +2 -2
- package/src/Icon/index.js +2 -2
- package/src/InputLabel/InputLabel.jsx +9 -2
- package/src/InputLabel/{LabelContent.web.jsx → LabelContent.jsx} +0 -0
- package/src/InputSupports/InputSupports.jsx +7 -18
- package/src/InputSupports/useInputSupports.js +30 -0
- package/src/Link/{InlinePressable.web.jsx → InlinePressable.jsx} +0 -0
- package/src/Link/LinkBase.jsx +14 -12
- package/src/Modal/Modal.jsx +185 -0
- package/src/Modal/dictionary.js +9 -0
- package/src/Modal/index.js +3 -0
- package/src/Notification/Notification.jsx +149 -0
- package/src/Notification/dictionary.js +8 -0
- package/src/Notification/index.js +3 -0
- package/src/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 +19 -56
- package/src/Radio/RadioButton.jsx +131 -0
- package/src/Radio/RadioGroup.jsx +198 -0
- package/src/Radio/{RadioInput.web.jsx → RadioInput.jsx} +0 -0
- package/src/Radio/index.js +2 -0
- package/src/RadioCard/RadioCard.jsx +191 -0
- package/src/RadioCard/RadioCardGroup.jsx +211 -0
- package/src/RadioCard/index.js +5 -0
- package/src/Search/Search.jsx +204 -0
- package/src/Search/dictionary.js +12 -0
- package/src/Search/index.js +3 -0
- package/src/Select/{Group.web.jsx → Group.jsx} +0 -0
- package/src/Select/{Item.web.jsx → Item.jsx} +0 -0
- package/src/Select/{Picker.web.jsx → Picker.jsx} +0 -0
- package/src/Select/Select.jsx +12 -22
- package/src/SideNav/Item.jsx +2 -2
- package/src/Skeleton/Skeleton.jsx +17 -20
- package/src/Skeleton/skeleton.constant.js +3 -0
- package/src/Skeleton/skeletonWebAnimation.js +13 -0
- package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
- package/src/StackView/StackView.jsx +10 -3
- package/src/StackView/StackWrap.jsx +9 -1
- package/src/StackView/StackWrapBox.jsx +4 -3
- package/src/StackView/StackWrapGap.jsx +3 -3
- package/src/StackView/getStackedContent.jsx +8 -2
- package/src/StepTracker/Step.jsx +202 -0
- package/src/StepTracker/StepTracker.jsx +163 -0
- package/src/StepTracker/dictionary.js +10 -0
- package/src/StepTracker/index.js +3 -0
- package/src/Tabs/HorizontalScroll.jsx +165 -0
- package/src/Tabs/ScrollViewEnd.jsx +53 -0
- package/src/Tabs/ScrollViewEnd.native.jsx +24 -0
- package/src/Tabs/Tabs.jsx +89 -0
- package/src/Tabs/TabsItem.jsx +204 -0
- package/src/Tabs/TabsScrollButton.jsx +100 -0
- package/src/Tabs/dictionary.js +11 -0
- package/src/Tabs/index.js +3 -0
- package/src/Tabs/itemPositions.js +101 -0
- package/src/Tags/Tags.jsx +2 -1
- package/src/TextInput/TextInputBase.jsx +12 -22
- package/src/ThemeProvider/useThemeTokens.js +2 -2
- package/src/ThemeProvider/utils/styles.js +18 -5
- package/src/ThemeProvider/utils/theme-tokens.js +46 -5
- package/src/ToggleSwitch/ToggleSwitch.jsx +2 -3
- package/src/Tooltip/{Backdrop.web.jsx → Backdrop.jsx} +0 -0
- package/src/Tooltip/Tooltip.jsx +1 -1
- package/src/TooltipButton/TooltipButton.jsx +23 -27
- package/src/Typography/Typography.jsx +6 -5
- package/src/index.js +20 -2
- package/src/utils/children.jsx +66 -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 +20 -12
- package/src/utils/pressability.js +4 -0
- package/src/utils/propTypes.js +98 -34
- package/src/utils/useCopy.js +30 -4
- package/src/utils/useHash.js +34 -0
- package/src/utils/useHash.native.js +6 -0
- package/stories/A11yText/A11yText.stories.jsx +4 -8
- package/stories/Checkbox/Checkbox.stories.jsx +24 -1
- package/stories/Icon/Icon.stories.jsx +6 -5
- package/stories/Modal/Modal.stories.jsx +29 -0
- package/stories/Notification/Notification.stories.jsx +82 -0
- 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/StepTracker/StepTracker.stories.jsx +71 -0
- package/stories/Tabs/Tabs.stories.jsx +97 -0
- package/stories/{platform-supports.web.jsx → platform-supports.jsx} +0 -0
- package/__fixtures__/accessible.icon.svg +0 -6
- package/babel.config.json +0 -8
- 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/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,200 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { Pressable, View, Text } from 'react-native'
|
|
3
|
+
import { fireEvent, render } from '@testing-library/react-native'
|
|
4
|
+
|
|
5
|
+
import { Tabs } from '../../src'
|
|
6
|
+
import {
|
|
7
|
+
getItemPositionLayoutHandler,
|
|
8
|
+
useItemPositions,
|
|
9
|
+
getItemPositionScrollTarget
|
|
10
|
+
} from '../../src/Tabs/itemPositions'
|
|
11
|
+
import Theme from '../../__fixtures__/Theme'
|
|
12
|
+
|
|
13
|
+
// ScrollViewRef.scrollTo doesn't work in Jest - unit-test the utilities instead
|
|
14
|
+
describe('Tabs getItemPositionScrollTarget', () => {
|
|
15
|
+
const positionsWithoutSpacing = {
|
|
16
|
+
0: { start: 0, end: 100 },
|
|
17
|
+
1: { start: 100, end: 200 },
|
|
18
|
+
2: { start: 200, end: 300 }
|
|
19
|
+
}
|
|
20
|
+
const positions = {
|
|
21
|
+
0: { start: 0, end: 50 },
|
|
22
|
+
1: { start: 100, end: 150 },
|
|
23
|
+
2: { start: 200, end: 250 }
|
|
24
|
+
}
|
|
25
|
+
it('scrolls to the start of an item rather than chopping it', () => {
|
|
26
|
+
const x = getItemPositionScrollTarget(150, 300, positionsWithoutSpacing)
|
|
27
|
+
expect(x).toBe(100)
|
|
28
|
+
})
|
|
29
|
+
it('offsets the position by a button clearance', () => {
|
|
30
|
+
const x = getItemPositionScrollTarget(150, 300, positionsWithoutSpacing, 20)
|
|
31
|
+
expect(x).toBe(80)
|
|
32
|
+
})
|
|
33
|
+
it('scrolls exactly if landing on a gap', () => {
|
|
34
|
+
const x = getItemPositionScrollTarget(170, 300, positions)
|
|
35
|
+
expect(x).toBe(170)
|
|
36
|
+
})
|
|
37
|
+
it('applies button clearance if landing on a gap', () => {
|
|
38
|
+
const x = getItemPositionScrollTarget(170, 300, positions, 40)
|
|
39
|
+
expect(x).toBe(130)
|
|
40
|
+
})
|
|
41
|
+
it('does not apply button clearance on reaching the end', () => {
|
|
42
|
+
const x = getItemPositionScrollTarget(300, 300, positions, 40)
|
|
43
|
+
expect(x).toBe(300)
|
|
44
|
+
})
|
|
45
|
+
it('does not exceed the maximum', () => {
|
|
46
|
+
const x = getItemPositionScrollTarget(320, 300, positions, 40)
|
|
47
|
+
expect(x).toBe(300)
|
|
48
|
+
})
|
|
49
|
+
it('does not go below 0', () => {
|
|
50
|
+
const x = getItemPositionScrollTarget(-420, 300, positions, 40)
|
|
51
|
+
expect(x).toBe(0)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// onLayout also doesn't work naturally in jest
|
|
56
|
+
describe('Tabs getItemPositionLayoutHandler', () => {
|
|
57
|
+
// Test component using useItemPositions with getItemPositionLayoutHandler
|
|
58
|
+
// that can be rerendered manually and that outputs itemPositions value
|
|
59
|
+
const MockComponent = () => {
|
|
60
|
+
const [num, setNum] = useState()
|
|
61
|
+
const [{ positions }] = useItemPositions()
|
|
62
|
+
return (
|
|
63
|
+
<View>
|
|
64
|
+
<View testID="onlayout[0]" onLayout={getItemPositionLayoutHandler(positions, 0)} />
|
|
65
|
+
<View testID="onlayout[1]" onLayout={getItemPositionLayoutHandler(positions, 1)} />
|
|
66
|
+
<Text testID="output">{JSON.stringify(positions)}</Text>
|
|
67
|
+
<Pressable testID="rerender" onPress={() => setNum(num + 1)}>
|
|
68
|
+
<Text>{num}</Text>
|
|
69
|
+
</Pressable>
|
|
70
|
+
</View>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
it('gets width and x positions from onLayout events', async () => {
|
|
74
|
+
const { getByTestId } = render(<MockComponent />)
|
|
75
|
+
|
|
76
|
+
// onLayout doesn't work in jest but can be called directly as an event, but we
|
|
77
|
+
// have to pass the event object. Can't test that it gets them correctly from style
|
|
78
|
+
await fireEvent(getByTestId('onlayout[0]'), 'layout', {
|
|
79
|
+
nativeEvent: {
|
|
80
|
+
layout: {
|
|
81
|
+
width: 200,
|
|
82
|
+
x: 0
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
await fireEvent(getByTestId('onlayout[1]'), 'layout', {
|
|
87
|
+
nativeEvent: {
|
|
88
|
+
layout: {
|
|
89
|
+
width: 100,
|
|
90
|
+
x: 250
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
await fireEvent.press(getByTestId('rerender'))
|
|
95
|
+
expect(getByTestId('output')).toHaveTextContent(
|
|
96
|
+
'{"0":{"start":0,"end":200},"1":{"start":250,"end":350}}'
|
|
97
|
+
)
|
|
98
|
+
})
|
|
99
|
+
it('does not cause a rerender from onLayout events alone', async () => {
|
|
100
|
+
const { getByTestId } = render(<MockComponent />)
|
|
101
|
+
|
|
102
|
+
expect(getByTestId('output')).toHaveTextContent('{}')
|
|
103
|
+
await fireEvent(getByTestId('onlayout[0]'), 'layout', {
|
|
104
|
+
nativeEvent: {
|
|
105
|
+
layout: {
|
|
106
|
+
width: 200,
|
|
107
|
+
x: 0
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
await fireEvent(getByTestId('onlayout[1]'), 'layout', {
|
|
112
|
+
nativeEvent: {
|
|
113
|
+
layout: {
|
|
114
|
+
width: 100,
|
|
115
|
+
x: 250
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
expect(getByTestId('output')).toHaveTextContent('{}')
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
describe('useItemPositions', () => {
|
|
124
|
+
// Again we're limited in what we can test; we can't test natural onLayout
|
|
125
|
+
// or page load timing, but we can affirm that calling `setIsReady` after layout
|
|
126
|
+
// events causes a re-render that can access positions data
|
|
127
|
+
const IsReadyMockComponent = () => {
|
|
128
|
+
const [{ positions, setIsReady }] = useItemPositions()
|
|
129
|
+
return (
|
|
130
|
+
<View testID="container" onLayout={setIsReady}>
|
|
131
|
+
<View testID="onlayout[0]" onLayout={getItemPositionLayoutHandler(positions, 0)} />
|
|
132
|
+
<View testID="onlayout[1]" onLayout={getItemPositionLayoutHandler(positions, 1)} />
|
|
133
|
+
<Text testID="output">{JSON.stringify(positions)}</Text>
|
|
134
|
+
</View>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
it('causes a rerender when setIsReady is called', async () => {
|
|
138
|
+
const { getByTestId } = render(<IsReadyMockComponent />)
|
|
139
|
+
|
|
140
|
+
expect(getByTestId('output')).toHaveTextContent('{}')
|
|
141
|
+
await fireEvent(getByTestId('onlayout[0]'), 'layout', {
|
|
142
|
+
nativeEvent: {
|
|
143
|
+
layout: {
|
|
144
|
+
width: 200,
|
|
145
|
+
x: 0
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
await fireEvent(getByTestId('onlayout[1]'), 'layout', {
|
|
150
|
+
nativeEvent: {
|
|
151
|
+
layout: {
|
|
152
|
+
width: 100,
|
|
153
|
+
x: 250
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
await fireEvent(getByTestId('container'), 'layout', {
|
|
158
|
+
nativeEvent: { layout: {} }
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
expect(getByTestId('output')).toHaveTextContent(
|
|
162
|
+
'{"0":{"start":0,"end":200},"1":{"start":250,"end":350}}'
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
describe('Tabs', () => {
|
|
168
|
+
const items = [{ label: 'one' }, { label: 'two' }, { label: 'three' }, { label: 'four' }]
|
|
169
|
+
const linkItems = items.map((item) => ({ ...item, href: 'https://telus.com' }))
|
|
170
|
+
|
|
171
|
+
it('renders a menu', () => {
|
|
172
|
+
const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
|
|
173
|
+
expect(queryAllByA11yRole('tablist')).toHaveLength(1)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('renders menuitems by default', () => {
|
|
177
|
+
const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
|
|
178
|
+
expect(queryAllByA11yRole('tab')).toHaveLength(4)
|
|
179
|
+
expect(queryAllByA11yRole('link')).toHaveLength(0)
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('renders links by if hrefs are passed', () => {
|
|
183
|
+
const { queryAllByA11yRole } = render(<Tabs items={linkItems} />, { wrapper: Theme })
|
|
184
|
+
expect(queryAllByA11yRole('tab')).toHaveLength(0)
|
|
185
|
+
expect(queryAllByA11yRole('link')).toHaveLength(4)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('is selected when pressed', () => {
|
|
189
|
+
const { queryByA11yState, getByText } = render(<Tabs items={items} />, { wrapper: Theme })
|
|
190
|
+
let selected
|
|
191
|
+
selected = queryByA11yState({ selected: true })
|
|
192
|
+
expect(selected).toBeFalsy()
|
|
193
|
+
|
|
194
|
+
fireEvent.press(getByText('two'))
|
|
195
|
+
|
|
196
|
+
selected = queryByA11yState({ selected: true })
|
|
197
|
+
expect(selected).toBeTruthy()
|
|
198
|
+
expect(selected).toHaveTextContent('two')
|
|
199
|
+
})
|
|
200
|
+
})
|
|
@@ -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')
|
|
@@ -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(
|
|
@@ -14,18 +14,29 @@ describe('useCopy hook', () => {
|
|
|
14
14
|
it('returns a correct english translation', () => {
|
|
15
15
|
const { result } = renderHook(() => useCopy({ dictionary, copy: 'en' }))
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const getCopy = result.current
|
|
18
|
+
expect(getCopy('translation key')).toBe('english version')
|
|
18
19
|
})
|
|
19
20
|
|
|
20
21
|
it('returns a correct french translation', () => {
|
|
21
22
|
const { result } = renderHook(() => useCopy({ dictionary, copy: 'fr' }))
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
const getCopy = result.current
|
|
25
|
+
expect(getCopy('translation key')).toBe('french version')
|
|
24
26
|
})
|
|
25
27
|
|
|
26
28
|
it('returns undefined when no translation is found', () => {
|
|
27
29
|
const { result } = renderHook(() => useCopy({ dictionary, copy: 'en' }))
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
const getCopy = result.current
|
|
32
|
+
expect(getCopy('non-existing key')).toBe(undefined)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('allows for overriding the entire dictionary with a copy object (ignoring the dictionary argument)', () => {
|
|
36
|
+
const { result } = renderHook(() => useCopy({ dictionary, copy: dictionary.en }))
|
|
37
|
+
|
|
38
|
+
const getCopy = result.current
|
|
39
|
+
expect(getCopy('non-existing key')).toBe(undefined)
|
|
40
|
+
expect(getCopy('translation key')).toBe('english version')
|
|
30
41
|
})
|
|
31
42
|
})
|
package/babel.config.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
/*
|
|
4
|
+
* we actually want this setup to be used whenever we're not in `test` but
|
|
5
|
+
* babel merges plugins array rather than replacing so we can't set it as a
|
|
6
|
+
* default. However the default BABEL_ENV value is development (jest sets it
|
|
7
|
+
* to test)
|
|
8
|
+
*/
|
|
9
|
+
development: {
|
|
10
|
+
presets: ['@babel/preset-env', ['@babel/preset-react', { runtime: 'automatic' }]],
|
|
11
|
+
plugins: [['react-native-web', { commonjs: true }]]
|
|
12
|
+
},
|
|
13
|
+
/*
|
|
14
|
+
* jest is testing for just ios at the moment, use a preset which best matches that env
|
|
15
|
+
*/
|
|
16
|
+
test: {
|
|
17
|
+
presets: ['module:metro-react-native-babel-preset']
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
package/jest.config.js
CHANGED
|
@@ -22,7 +22,7 @@ module.exports = {
|
|
|
22
22
|
'.+\\.(otf|svg|png|jpg)$': 'identity-obj-proxy'
|
|
23
23
|
},
|
|
24
24
|
transformIgnorePatterns: [
|
|
25
|
-
'node_modules/(?!(jest-)?react-native|@react-native-community|@react-native-picker)'
|
|
25
|
+
'node_modules/(?!(jest-)?react-native|@react-native|@react-native-community|@react-native-picker)'
|
|
26
26
|
],
|
|
27
27
|
// Count everything in src when calculating coverage
|
|
28
28
|
collectCoverageFrom: ['src/**/*.{js,jsx}']
|
|
@@ -1,58 +1,86 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useA11yInfo = exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _AccessibilityInfo = _interopRequireDefault(require("react-native-web/dist/cjs/exports/AccessibilityInfo"));
|
|
13
|
+
|
|
14
|
+
var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
|
|
15
|
+
|
|
16
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
|
+
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
+
|
|
20
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
|
+
|
|
22
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
|
+
|
|
24
|
+
const ScreenReaderContext = /*#__PURE__*/(0, _react.createContext)(false);
|
|
25
|
+
const ReducedMotionContext = /*#__PURE__*/(0, _react.createContext)(false);
|
|
6
26
|
|
|
7
27
|
const A11yInfoProvider = ({
|
|
8
28
|
children
|
|
9
29
|
}) => {
|
|
10
|
-
const [reduceMotionEnabled, setReduceMotionEnabled] = useState(false);
|
|
11
|
-
const [screenReaderEnabled, setScreenReaderEnabled] = useState(false);
|
|
12
|
-
useEffect(() => {
|
|
30
|
+
const [reduceMotionEnabled, setReduceMotionEnabled] = (0, _react.useState)(false);
|
|
31
|
+
const [screenReaderEnabled, setScreenReaderEnabled] = (0, _react.useState)(false);
|
|
32
|
+
(0, _react.useEffect)(() => {
|
|
13
33
|
if (process.env.NODE_ENV === 'test') {
|
|
14
34
|
// On Jest these effects do nothing but can cause `act` state change warnings
|
|
15
35
|
// and "...after the Jest environment has been torn down" errors, so skip them.
|
|
16
36
|
return () => {};
|
|
17
37
|
}
|
|
18
38
|
|
|
19
|
-
|
|
20
|
-
|
|
39
|
+
_AccessibilityInfo.default.addEventListener('reduceMotionChanged', setReduceMotionEnabled);
|
|
40
|
+
|
|
41
|
+
_AccessibilityInfo.default.addEventListener('screenReaderChanged', setScreenReaderEnabled);
|
|
21
42
|
|
|
22
43
|
const setInitialA11yInfo = async () => {
|
|
23
|
-
const [initialReduceMotionEnabled, initialScreenReaderEnabled] = await Promise.all([
|
|
44
|
+
const [initialReduceMotionEnabled, initialScreenReaderEnabled] = await Promise.all([_AccessibilityInfo.default.isReduceMotionEnabled(), _AccessibilityInfo.default.isScreenReaderEnabled()]); // Browsers can't detect screen readers; in RNW isScreenReaderEnabled() is always `true`
|
|
24
45
|
// https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/AccessibilityInfo/index.js#L14
|
|
25
46
|
|
|
26
|
-
setScreenReaderEnabled(
|
|
47
|
+
setScreenReaderEnabled(_Platform.default.OS !== 'web' && !!initialScreenReaderEnabled); // RNW does support isReduceMotionEnabled looking for 'prefers-reduced-motion' state
|
|
27
48
|
|
|
28
49
|
setReduceMotionEnabled(!!initialReduceMotionEnabled);
|
|
29
50
|
};
|
|
30
51
|
|
|
31
|
-
if (
|
|
52
|
+
if (_AccessibilityInfo.default.isReduceMotionEnabled && _AccessibilityInfo.default.isScreenReaderEnabled) {
|
|
32
53
|
setInitialA11yInfo();
|
|
33
54
|
}
|
|
34
55
|
|
|
35
56
|
return () => {
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
_AccessibilityInfo.default.removeEventListener('reduceMotionChanged', setReduceMotionEnabled);
|
|
58
|
+
|
|
59
|
+
_AccessibilityInfo.default.removeEventListener('screenReaderChanged', setScreenReaderEnabled);
|
|
38
60
|
};
|
|
39
61
|
}, []);
|
|
40
|
-
return /*#__PURE__*/
|
|
41
|
-
value: reduceMotionEnabled
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ReducedMotionContext.Provider, {
|
|
63
|
+
value: reduceMotionEnabled,
|
|
64
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ScreenReaderContext.Provider, {
|
|
65
|
+
value: screenReaderEnabled,
|
|
66
|
+
children: children
|
|
67
|
+
})
|
|
68
|
+
});
|
|
45
69
|
};
|
|
46
70
|
|
|
47
71
|
A11yInfoProvider.propTypes = {
|
|
48
|
-
children:
|
|
72
|
+
children: _propTypes.default.node.isRequired
|
|
49
73
|
};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
74
|
+
var _default = A11yInfoProvider;
|
|
75
|
+
exports.default = _default;
|
|
76
|
+
|
|
77
|
+
const useA11yInfo = () => {
|
|
78
|
+
const screenReaderEnabled = (0, _react.useContext)(ScreenReaderContext);
|
|
79
|
+
const reduceMotionEnabled = (0, _react.useContext)(ReducedMotionContext);
|
|
54
80
|
return {
|
|
55
81
|
reduceMotionEnabled,
|
|
56
82
|
screenReaderEnabled
|
|
57
83
|
};
|
|
58
|
-
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
exports.useA11yInfo = useA11yInfo;
|
package/lib/A11yText/index.js
CHANGED
|
@@ -1,39 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
|
|
11
|
+
|
|
12
|
+
var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
|
|
13
|
+
|
|
14
|
+
var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
|
|
15
|
+
|
|
16
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
17
|
+
|
|
18
|
+
var _propTypes2 = require("../utils/propTypes");
|
|
19
|
+
|
|
20
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
|
+
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
|
|
5
24
|
/**
|
|
6
25
|
* A11yText is a zero-size invisible element that adds text to be read by screen readers.
|
|
7
26
|
*
|
|
8
27
|
* It should be used to add selectable screen-reader-only text to the main document flow,
|
|
9
28
|
* as a sibling to blocks of text like paragraphs and interactive elements like buttons.
|
|
10
29
|
*/
|
|
11
|
-
|
|
12
30
|
const A11yText = ({
|
|
13
31
|
text,
|
|
14
32
|
heading,
|
|
15
33
|
...rest
|
|
16
34
|
}) => {
|
|
17
|
-
const a11y = a11yProps.select({
|
|
35
|
+
const a11y = _propTypes2.a11yProps.select({
|
|
18
36
|
// On iOS, needs `accessible` to be true to be focusable without non-a11y content.
|
|
19
37
|
// On Web, `accessible` causes RNW to set attributes that may make the element be treated as a group.
|
|
20
38
|
// On Android, may cause this to be skipped when with `<Text>` siblings in an `accessible` View,
|
|
21
39
|
// see https://github.com/facebook/react-native/issues/30851#issuecomment-790165489
|
|
22
|
-
accessible:
|
|
40
|
+
accessible: _Platform.default.OS === 'ios',
|
|
23
41
|
accessibilityLabel: text,
|
|
24
42
|
accessibilityRole: heading ? 'header' : 'text',
|
|
25
43
|
...rest
|
|
26
44
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
45
|
+
|
|
46
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
47
|
+
style: styles.invisible,
|
|
48
|
+
...a11y
|
|
49
|
+
});
|
|
30
50
|
};
|
|
31
51
|
|
|
32
52
|
A11yText.propTypes = {
|
|
33
|
-
text:
|
|
34
|
-
heading:
|
|
53
|
+
text: _propTypes.default.string.isRequired,
|
|
54
|
+
heading: _propTypes.default.bool
|
|
35
55
|
};
|
|
36
|
-
|
|
56
|
+
|
|
57
|
+
const styles = _StyleSheet.default.create({
|
|
37
58
|
invisible: {
|
|
38
59
|
// Without width or height it is not shown
|
|
39
60
|
minHeight: 1,
|
|
@@ -46,4 +67,6 @@ const styles = StyleSheet.create({
|
|
|
46
67
|
top: -1
|
|
47
68
|
}
|
|
48
69
|
});
|
|
49
|
-
|
|
70
|
+
|
|
71
|
+
var _default = A11yText;
|
|
72
|
+
exports.default = _default;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _shared = require("./shared");
|
|
11
|
+
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
const SVG_RADIUS = 20;
|
|
17
|
+
const SVG_CIRCUMFERENCE = SVG_RADIUS * 2 * Math.PI;
|
|
18
|
+
const MIN_SVG_LENGTH = _shared.MIN_STROKE_ANGLE / 360 * SVG_CIRCUMFERENCE;
|
|
19
|
+
const MAX_SVG_LENGTH = (1 - _shared.MIN_EMPTY_ANGLE / 360) * SVG_CIRCUMFERENCE;
|
|
20
|
+
const animationProps = {
|
|
21
|
+
begin: '0s',
|
|
22
|
+
dur: "".concat(_shared.DURATION, "ms"),
|
|
23
|
+
fill: 'freeze',
|
|
24
|
+
repeatCount: 'indefinite'
|
|
25
|
+
};
|
|
26
|
+
const bezierProps = {
|
|
27
|
+
calcMode: 'spline',
|
|
28
|
+
keyTimes: '0; 0.5; 1',
|
|
29
|
+
keySplines: "".concat(_shared.BEZIER.join(', '), " ; ").concat(_shared.BEZIER.join(', '))
|
|
30
|
+
}; // We're using svg rather than css here to define the animation to avoid needing to introduce css injection mechanism
|
|
31
|
+
// It's possible to replicate this functionality with RNW animations, but it snags on chrome at least, see https://github.com/telus/universal-design-system/pull/477 for details.
|
|
32
|
+
|
|
33
|
+
const Spinner = ({
|
|
34
|
+
size,
|
|
35
|
+
color,
|
|
36
|
+
thickness,
|
|
37
|
+
label
|
|
38
|
+
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
|
|
39
|
+
width: "".concat(size, "px"),
|
|
40
|
+
height: "".concat(size, "px"),
|
|
41
|
+
viewBox: "0 0 48 48",
|
|
42
|
+
"aria-valuetext": label,
|
|
43
|
+
role: "progressbar",
|
|
44
|
+
"aria-busy": true,
|
|
45
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("g", {
|
|
46
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("animateTransform", {
|
|
47
|
+
attributeName: "transform",
|
|
48
|
+
type: "rotate",
|
|
49
|
+
values: "-180 24 24;".concat(360 + _shared.MIN_STROKE_ANGLE - 180, " 24 24"),
|
|
50
|
+
...animationProps
|
|
51
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("circle", {
|
|
52
|
+
fill: "none",
|
|
53
|
+
stroke: color,
|
|
54
|
+
strokeWidth: thickness * 48 / size,
|
|
55
|
+
strokeLinecap: "round",
|
|
56
|
+
cx: "24",
|
|
57
|
+
cy: "24",
|
|
58
|
+
r: "20",
|
|
59
|
+
strokeDasharray: [MIN_SVG_LENGTH, SVG_CIRCUMFERENCE],
|
|
60
|
+
strokeDashoffset: 0,
|
|
61
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("animate", {
|
|
62
|
+
attributeName: "stroke-dashoffset",
|
|
63
|
+
values: "0;-10;".concat(MIN_SVG_LENGTH - SVG_CIRCUMFERENCE),
|
|
64
|
+
...animationProps,
|
|
65
|
+
...bezierProps
|
|
66
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("animate", {
|
|
67
|
+
attributeName: "stroke-dasharray",
|
|
68
|
+
values: "".concat(MIN_SVG_LENGTH, ", 200;").concat(MAX_SVG_LENGTH, ", 200;").concat(MIN_SVG_LENGTH, ", 200"),
|
|
69
|
+
...animationProps,
|
|
70
|
+
...bezierProps
|
|
71
|
+
})]
|
|
72
|
+
})]
|
|
73
|
+
})
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
Spinner.propTypes = _shared.propTypes;
|
|
77
|
+
var _default = Spinner;
|
|
78
|
+
exports.default = _default;
|