@telus-uds/components-base 1.25.0 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +46 -2
  2. package/component-docs.json +57 -2
  3. package/lib/Button/ButtonBase.js +2 -1
  4. package/lib/Carousel/Carousel.js +19 -1
  5. package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +11 -2
  6. package/lib/MultiSelectFilter/ModalOverlay.js +136 -0
  7. package/lib/MultiSelectFilter/MultiSelectFilter.js +64 -26
  8. package/lib-module/Button/ButtonBase.js +2 -1
  9. package/lib-module/Carousel/Carousel.js +16 -1
  10. package/lib-module/Carousel/CarouselStepTracker/CarouselStepTracker.js +10 -2
  11. package/lib-module/MultiSelectFilter/ModalOverlay.js +112 -0
  12. package/lib-module/MultiSelectFilter/MultiSelectFilter.js +65 -27
  13. package/package.json +2 -2
  14. package/src/Button/ButtonBase.jsx +1 -1
  15. package/src/Carousel/Carousel.jsx +16 -2
  16. package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +7 -1
  17. package/src/MultiSelectFilter/ModalOverlay.jsx +86 -0
  18. package/src/MultiSelectFilter/MultiSelectFilter.jsx +73 -49
  19. package/.eslintrc.js +0 -9
  20. package/__tests17__/A11yText/A11yText.test.jsx +0 -34
  21. package/__tests17__/ActivityIndicator/ActivityIndicator.test.jsx +0 -68
  22. package/__tests17__/ActivityIndicator/__snapshots__/ActivityIndicator.test.jsx.snap +0 -299
  23. package/__tests17__/Box/Box.test.jsx +0 -111
  24. package/__tests17__/Button/Button.test.jsx +0 -86
  25. package/__tests17__/Button/ButtonBase.test.jsx +0 -82
  26. package/__tests17__/Button/ButtonGroup.test.jsx +0 -347
  27. package/__tests17__/Button/ButtonLink.test.jsx +0 -61
  28. package/__tests17__/Card/Card.test.jsx +0 -63
  29. package/__tests17__/Carousel/Carousel.test.jsx +0 -128
  30. package/__tests17__/Carousel/CarouselTabs.test.jsx +0 -142
  31. package/__tests17__/Checkbox/Checkbox.test.jsx +0 -94
  32. package/__tests17__/Checkbox/CheckboxGroup.test.jsx +0 -246
  33. package/__tests17__/Divider/Divider.test.jsx +0 -91
  34. package/__tests17__/ExpandCollapse/ExpandCollapse.test.jsx +0 -109
  35. package/__tests17__/Feedback/Feedback.test.jsx +0 -42
  36. package/__tests17__/FlexGrid/Col.test.jsx +0 -261
  37. package/__tests17__/FlexGrid/FlexGrid.test.jsx +0 -136
  38. package/__tests17__/FlexGrid/Row.test.jsx +0 -273
  39. package/__tests17__/HorizontalScroll/HorizontalScroll.test.jsx +0 -165
  40. package/__tests17__/Icon/Icon.test.jsx +0 -61
  41. package/__tests17__/IconButton/IconButton.test.jsx +0 -52
  42. package/__tests17__/InputLabel/InputLabel.test.jsx +0 -28
  43. package/__tests17__/InputLabel/__snapshots__/InputLabel.test.jsx.snap +0 -3
  44. package/__tests17__/InputSupports/InputSupports.test.jsx +0 -60
  45. package/__tests17__/Link/Link.test.jsx +0 -63
  46. package/__tests17__/Link/TextButton.test.jsx +0 -35
  47. package/__tests17__/List/List.test.jsx +0 -82
  48. package/__tests17__/Modal/Modal.test.jsx +0 -47
  49. package/__tests17__/Notification/Notification.test.jsx +0 -20
  50. package/__tests17__/Pagination/Pagination.test.jsx +0 -160
  51. package/__tests17__/Progress/Progress.test.jsx +0 -79
  52. package/__tests17__/Radio/Radio.test.jsx +0 -87
  53. package/__tests17__/Radio/RadioGroup.test.jsx +0 -220
  54. package/__tests17__/RadioCard/RadioCard.test.jsx +0 -87
  55. package/__tests17__/RadioCard/RadioCardGroup.test.jsx +0 -246
  56. package/__tests17__/Search/Search.test.jsx +0 -87
  57. package/__tests17__/Select/Select.test.jsx +0 -94
  58. package/__tests17__/SideNav/SideNav.test.jsx +0 -110
  59. package/__tests17__/Skeleton/Skeleton.test.jsx +0 -61
  60. package/__tests17__/SkipLink/SkipLink.test.jsx +0 -61
  61. package/__tests17__/Spacer/Spacer.test.jsx +0 -63
  62. package/__tests17__/StackView/StackView.test.jsx +0 -211
  63. package/__tests17__/StackView/StackWrap.test.jsx +0 -47
  64. package/__tests17__/StackView/getStackedContent.test.jsx +0 -295
  65. package/__tests17__/StepTracker/StepTracker.test.jsx +0 -108
  66. package/__tests17__/Tabs/Tabs.test.jsx +0 -49
  67. package/__tests17__/Tags/Tags.test.jsx +0 -327
  68. package/__tests17__/TextInput/TextArea.test.jsx +0 -35
  69. package/__tests17__/TextInput/TextInputBase.test.jsx +0 -125
  70. package/__tests17__/ThemeProvider/ThemeProvider.test.jsx +0 -82
  71. package/__tests17__/ThemeProvider/useThemeTokens.test.jsx +0 -514
  72. package/__tests17__/ThemeProvider/utils/theme-tokens.test.js +0 -41
  73. package/__tests17__/ToggleSwitch/ToggleSwitch.test.jsx +0 -82
  74. package/__tests17__/ToggleSwitch/ToggleSwitchGroup.test.jsx +0 -192
  75. package/__tests17__/Tooltip/Tooltip.test.jsx +0 -65
  76. package/__tests17__/Tooltip/getTooltipPosition.test.js +0 -79
  77. package/__tests17__/Typography/typography.test.jsx +0 -90
  78. package/__tests17__/utils/children.test.jsx +0 -128
  79. package/__tests17__/utils/containUniqueFields.test.js +0 -25
  80. package/__tests17__/utils/input.test.js +0 -375
  81. package/__tests17__/utils/props.test.js +0 -36
  82. package/__tests17__/utils/semantics.test.jsx +0 -34
  83. package/__tests17__/utils/useCopy.test.js +0 -42
  84. package/__tests17__/utils/useResponsiveProp.test.jsx +0 -202
  85. package/__tests17__/utils/useSpacingScale.test.jsx +0 -273
  86. package/__tests17__/utils/useUniqueId.test.js +0 -31
@@ -1,63 +0,0 @@
1
- import React from 'react'
2
- import { Platform, Linking } from 'react-native'
3
- import { render, fireEvent } from '@testing-library/react-native'
4
-
5
- import Theme from '../../__fixtures__/Theme'
6
- import Link from '../../src/Link/Link'
7
-
8
- const href = 'https://example.com'
9
-
10
- describe('Link', () => {
11
- it('renders an accessible link', async () => {
12
- const label = 'Test link text'
13
- const { getByRole } = render(
14
- <Theme>
15
- <Link href={href}>{label}</Link>
16
- </Theme>
17
- )
18
-
19
- const link = getByRole('link')
20
- expect(link).toHaveTextContent(label)
21
- })
22
-
23
- // TODO: this won't be called until cross-platform Jest tests are configured
24
- // see https://github.com/telus/universal-design-system/issues/319
25
- if (Platform.OS === 'web') {
26
- it('defers to platform link handling (web)', async () => {
27
- // This test is untested
28
- const label = 'Click me'
29
- jest.spyOn(Linking, 'openURL')
30
- const originalValue = Platform.OS
31
- Platform.OS = 'web'
32
- const { getByRole } = render(
33
- <Theme>
34
- <Link href={href}>{label}</Link>
35
- </Theme>
36
- )
37
-
38
- const el = getByRole('link')
39
- fireEvent.press(el)
40
- expect(Linking.openURL).not.toHaveBeenCalled()
41
- Platform.OS = originalValue
42
- })
43
- }
44
-
45
- // Default jest OS is ios, this will always be called until
46
- // https://github.com/telus/universal-design-system/issues/319
47
- if (Platform.OS !== 'web') {
48
- it('calls Linking.openURL (mobile)', async () => {
49
- const label = 'Click me'
50
- jest.spyOn(Linking, 'openURL').mockImplementation(() => {})
51
- const { getByRole } = render(
52
- <Theme>
53
- <Link href={href}>{label}</Link>
54
- </Theme>
55
- )
56
-
57
- const el = getByRole('link')
58
- fireEvent.press(el)
59
- expect(Linking.openURL).toHaveBeenCalledTimes(1)
60
- expect(Linking.openURL).toHaveBeenCalledWith(href)
61
- })
62
- }
63
- })
@@ -1,35 +0,0 @@
1
- import React from 'react'
2
- import { render, fireEvent } from '@testing-library/react-native'
3
-
4
- import Theme from '../../__fixtures__/Theme'
5
- import TextButton from '../../src/Link/TextButton'
6
-
7
- const label = 'Test TextButton'
8
-
9
- describe('Link', () => {
10
- it('renders with button role', async () => {
11
- const { getByRole } = render(
12
- <Theme>
13
- <TextButton onPress={() => {}}>{label}</TextButton>
14
- </Theme>
15
- )
16
-
17
- const textButton = getByRole('button')
18
- expect(textButton).toHaveTextContent(label)
19
- })
20
-
21
- it('renders a pressable button', async () => {
22
- const handlePress = jest.fn()
23
- const { getByText } = render(
24
- <Theme>
25
- <TextButton onPress={handlePress}>{label}</TextButton>
26
- </Theme>
27
- )
28
-
29
- const textButton = getByText(label)
30
-
31
- expect(handlePress).toHaveBeenCalledTimes(0)
32
- await fireEvent.press(textButton)
33
- expect(handlePress).toHaveBeenCalledTimes(1)
34
- })
35
- })
@@ -1,82 +0,0 @@
1
- import React from 'react'
2
- import { Text } from 'react-native'
3
- import { render } from '@testing-library/react-native'
4
- import { List } from '../../src'
5
- import Theme from '../../__fixtures__/Theme'
6
- import testTheme from '../../__fixtures__/testTheme'
7
- import { getFirstAncestorOfType } from '../../__fixtures__/test-utils'
8
- import ListItemBase from '../../src/List/ListItemBase'
9
-
10
- const setup = ({ showDivider = false, icon, children } = {}) =>
11
- render(
12
- <Theme>
13
- <List showDivider={showDivider}>
14
- <List.Item icon={icon}>{children || 'Item'}</List.Item>
15
- <List.Item icon={icon}>{children || 'Item'}</List.Item>
16
- <List.Item icon={icon}>{children || 'Item'}</List.Item>
17
- <List.Item icon={icon}>{children || 'Item'}</List.Item>
18
- </List>
19
- </Theme>
20
- )
21
-
22
- describe('List', () => {
23
- it('should render bullets by default', () => {
24
- const { queryAllByTestId } = setup()
25
- const bullet = queryAllByTestId('unordered-item-bullet')
26
- expect(bullet.length).toBe(4)
27
- })
28
-
29
- it('should render dividers for all items except for the last one', () => {
30
- const { getAllByText } = setup({ showDivider: true })
31
- const {
32
- interItemMarginWithDivider: marginBottom,
33
- dividerColor: borderColor,
34
- dividerSize: borderBottomWidth
35
- } = testTheme.components.List.tokens
36
-
37
- const listItemTypographies = getAllByText('Item')
38
-
39
- listItemTypographies.forEach((typography, index) => {
40
- // React Native has no listitem role (Jest defaults to ios), so to test the rendered List.Item style,
41
- // walk up tree to ListItemBase, which is a forwardRef, then down one to the actual element.
42
- // Web tests could use listitem role (see https://github.com/telus/universal-design-system/issues/319)
43
- const item = getFirstAncestorOfType(typography, ListItemBase).children[0]
44
- if (index + 1 !== listItemTypographies.length) {
45
- expect(item).toHaveStyle({ marginBottom, borderColor, borderBottomWidth })
46
- } else {
47
- expect(item).toHaveStyle({})
48
- }
49
- })
50
- })
51
-
52
- it('should render the icon when defined', () => {
53
- const { queryAllByTestId } = setup({ icon: () => <Text testID="icon" /> })
54
-
55
- const icons = queryAllByTestId('icon')
56
-
57
- expect(icons.length).toBe(4)
58
- })
59
- it('should allow children nested components', () => {
60
- const { queryAllByTestId } = setup({ children: <Text testID="child" /> })
61
-
62
- const children = queryAllByTestId('child')
63
-
64
- expect(children.length).toBe(4)
65
- })
66
- it('can set passed-down props at List and/or List.Item level', () => {
67
- const { getByText } = render(
68
- <Theme>
69
- <List tokens={{ itemFontSize: 123 }}>
70
- <List.Item>one</List.Item>
71
- <List.Item tokens={{ itemFontSize: 321 }}>two</List.Item>
72
- <List.Item tokens={null}>three</List.Item>
73
- </List>
74
- </Theme>
75
- )
76
- expect(getByText('one')).toHaveStyle({ fontSize: 123 })
77
- expect(getByText('two')).toHaveStyle({ fontSize: 321 })
78
- expect(getByText('three')).toHaveStyle({
79
- fontSize: testTheme.components.List.tokens.itemFontSize
80
- })
81
- })
82
- })
@@ -1,47 +0,0 @@
1
- import React from 'react'
2
- import { Text } from 'react-native'
3
- import { fireEvent, render } from '@testing-library/react-native'
4
-
5
- import { Modal } from '../../src'
6
- import Theme from '../../__fixtures__/Theme'
7
-
8
- describe('Modal', () => {
9
- it('is not rendered when closed', () => {
10
- const { queryByText } = render(
11
- <Modal>
12
- <Text>Test content</Text>
13
- </Modal>,
14
- { wrapper: Theme }
15
- )
16
-
17
- expect(queryByText('Test content')).toBeFalsy()
18
- })
19
-
20
- it('is rendered when open', () => {
21
- const { queryByText } = render(
22
- <Modal isOpen>
23
- <Text>Test content</Text>
24
- </Modal>,
25
- { wrapper: Theme }
26
- )
27
-
28
- expect(queryByText('Test content')).not.toBeFalsy()
29
- })
30
-
31
- it('onClose callback is triggered when closing', () => {
32
- const onClose = jest.fn()
33
-
34
- const { getByA11yRole } = render(
35
- <Modal isOpen onClose={onClose}>
36
- <Text>Test content</Text>
37
- </Modal>,
38
- { wrapper: Theme }
39
- )
40
-
41
- expect(onClose).not.toHaveBeenCalled()
42
-
43
- fireEvent.press(getByA11yRole('button'))
44
-
45
- expect(onClose).toHaveBeenCalledTimes(1)
46
- })
47
- })
@@ -1,20 +0,0 @@
1
- import React from 'react'
2
- import { fireEvent, render } from '@testing-library/react-native'
3
-
4
- import { Notification } from '../../src'
5
- import Theme from '../../__fixtures__/Theme'
6
-
7
- describe('Notification', () => {
8
- it('is removed when dismiss button is pressed', () => {
9
- const content = 'Notification content lands here'
10
- const { getByRole, getByText } = render(<Notification dismissible>{content}</Notification>, {
11
- wrapper: Theme
12
- })
13
-
14
- expect(() => getByText(content)).not.toThrow()
15
-
16
- fireEvent.press(getByRole('button'))
17
-
18
- expect(() => getByText(content)).toThrow()
19
- })
20
- })
@@ -1,160 +0,0 @@
1
- import React from 'react'
2
- import { render, fireEvent } from '@testing-library/react-native'
3
-
4
- import { Pagination } from '../../src'
5
- import Theme from '../../__fixtures__/Theme'
6
- import Viewport from '../../__fixtures__/Viewport'
7
-
8
- // eslint-disable-next-line react/prop-types
9
- const Wrapper = ({ children }) => (
10
- <Viewport viewport="xs">
11
- <Theme>{children}</Theme>
12
- </Viewport>
13
- )
14
-
15
- describe('Pagination', () => {
16
- it('truncates the number of rendered elements', () => {
17
- const { getByText } = render(
18
- <Pagination tokens={{ truncateAbove: 3 }}>
19
- <Pagination.PageButton onPress={() => {}} />
20
- <Pagination.PageButton onPress={() => {}} />
21
- <Pagination.PageButton onPress={() => {}} />
22
- <Pagination.PageButton onPress={() => {}} />
23
- <Pagination.PageButton onPress={() => {}} />
24
- </Pagination>,
25
- {
26
- wrapper: Wrapper
27
- }
28
- )
29
-
30
- expect(() => getByText('1')).not.toThrow()
31
- expect(() => getByText('2')).not.toThrow()
32
- expect(() => getByText('...')).not.toThrow()
33
- expect(() => getByText('3')).toThrow()
34
- expect(() => getByText('4')).toThrow()
35
- expect(() => getByText('5')).not.toThrow()
36
- })
37
-
38
- it('renders the "Next Page" button when applicable', () => {
39
- const { getByA11yLabel } = render(
40
- <Pagination>
41
- <Pagination.PageButton onPress={() => {}} isActive />
42
- <Pagination.PageButton onPress={() => {}} />
43
- </Pagination>,
44
- {
45
- wrapper: Wrapper
46
- }
47
- )
48
-
49
- expect(() => getByA11yLabel(/next/)).not.toThrow()
50
- expect(() => getByA11yLabel(/previous/)).toThrow()
51
- })
52
-
53
- it('renders the "Previous Page" button when applicable', () => {
54
- const { getByA11yLabel } = render(
55
- <Pagination>
56
- <Pagination.PageButton onPress={() => {}} />
57
- <Pagination.PageButton onPress={() => {}} isActive />
58
- </Pagination>,
59
- {
60
- wrapper: Wrapper
61
- }
62
- )
63
-
64
- expect(() => getByA11yLabel(/next/)).toThrow()
65
- expect(() => getByA11yLabel(/previous/)).not.toThrow()
66
- })
67
-
68
- it('uses correct copy', () => {
69
- const { getByA11yLabel } = render(
70
- <Pagination copy="fr">
71
- <Pagination.PageButton onPress={() => {}} isActive />
72
- </Pagination>,
73
- {
74
- wrapper: Wrapper
75
- }
76
- )
77
-
78
- expect(() => getByA11yLabel(/page actuelle/)).not.toThrow()
79
- })
80
-
81
- describe('Pagination Page Button', () => {
82
- it('triggers the onPress callback when pressed', () => {
83
- const onPress = jest.fn()
84
-
85
- const { getByA11yLabel } = render(
86
- <Pagination>
87
- <Pagination.PageButton onPress={() => {}} isActive />
88
- <Pagination.PageButton onPress={onPress} />
89
- </Pagination>,
90
- {
91
- wrapper: Wrapper
92
- }
93
- )
94
-
95
- expect(onPress).not.toHaveBeenCalled()
96
-
97
- fireEvent.press(getByA11yLabel('Go to page number 2'))
98
-
99
- expect(onPress).toHaveBeenCalledTimes(1)
100
- })
101
-
102
- it('renders a link and passes down hrefAttrs', () => {
103
- const { getByA11yLabel } = render(
104
- <Pagination>
105
- <Pagination.PageButton onPress={() => {}} isActive />
106
- <Pagination.PageButton href="test-url" hrefAttrs={{ target: '_blank' }} />
107
- </Pagination>,
108
- {
109
- wrapper: Wrapper
110
- }
111
- )
112
-
113
- const button = getByA11yLabel('Go to page number 2')
114
-
115
- expect(button).toHaveProp('accessibilityRole', 'link')
116
- expect(button).toHaveProp('href', 'test-url')
117
- expect(button).toHaveProp('hrefAttrs', { target: '_blank' })
118
- })
119
- })
120
-
121
- describe('Pagination Side Button', () => {
122
- it('triggers the onPress event of the item next to the active one', () => {
123
- const onPress = jest.fn()
124
-
125
- const { getByA11yLabel } = render(
126
- <Pagination>
127
- <Pagination.PageButton onPress={() => {}} isActive />
128
- <Pagination.PageButton onPress={onPress} />
129
- </Pagination>,
130
- {
131
- wrapper: Wrapper
132
- }
133
- )
134
-
135
- expect(onPress).not.toHaveBeenCalled()
136
-
137
- fireEvent.press(getByA11yLabel(/next/))
138
-
139
- expect(onPress).toHaveBeenCalledTimes(1)
140
- })
141
-
142
- it('renders a link with href props of the item next to the active one', () => {
143
- const { getByA11yLabel } = render(
144
- <Pagination>
145
- <Pagination.PageButton onPress={() => {}} isActive />
146
- <Pagination.PageButton href="test-url" hrefAttrs={{ target: '_blank' }} />
147
- </Pagination>,
148
- {
149
- wrapper: Wrapper
150
- }
151
- )
152
-
153
- const button = getByA11yLabel(/next/)
154
-
155
- expect(button).toHaveProp('accessibilityRole', 'link')
156
- expect(button).toHaveProp('href', 'test-url')
157
- expect(button).toHaveProp('hrefAttrs', { target: '_blank' })
158
- })
159
- })
160
- })
@@ -1,79 +0,0 @@
1
- import React from 'react'
2
- import { Text } from 'react-native'
3
- import { render, within } from '@testing-library/react-native'
4
-
5
- import { Progress } from '../../src'
6
- import Theme from '../../__fixtures__/Theme'
7
-
8
- const barTokens = {
9
- backgroundColor: 'green'
10
- }
11
- const percentage = 75
12
- const progressTokens = {
13
- backgroundColor: 'white',
14
- borderColor: 'black'
15
- }
16
- const a11yLabel = 'Progress bar'
17
- const progressA11yLabel = 'This is a progress indicator'
18
- const setup = (
19
- { children, ...props } = {
20
- children: (
21
- <Progress.Bar percentage={percentage} tokens={barTokens} accessibilityLabel={a11yLabel} />
22
- )
23
- }
24
- ) =>
25
- render(
26
- <Progress tokens={progressTokens} accessibilityLabel={progressA11yLabel} {...props}>
27
- {children}
28
- </Progress>,
29
- { wrapper: Theme }
30
- )
31
-
32
- describe('Progress', () => {
33
- it('renders with correct percentage and applies tokens accordingly', () => {
34
- const { getByA11yLabel } = setup()
35
- expect(getByA11yLabel(progressA11yLabel)).toHaveStyle(progressTokens)
36
- expect(getByA11yLabel(a11yLabel)).toHaveStyle({
37
- width: `${percentage}%`,
38
- ...barTokens
39
- })
40
- })
41
-
42
- it('renders arbitrary content inside the progress bar', () => {
43
- const contentText = 'This can be an arbitrary content'
44
- const { getByA11yLabel } = setup({
45
- children: (
46
- <Progress.Bar percentage={percentage} tokens={barTokens} accessibilityLabel={a11yLabel}>
47
- <Text>{contentText}</Text>
48
- </Progress.Bar>
49
- )
50
- })
51
- expect(within(getByA11yLabel(a11yLabel)).getByText(contentText)).toBeTruthy()
52
- })
53
-
54
- it('renders proper accessibility attributes on the progress bar', () => {
55
- const { getByA11yRole, getByA11yValue } = setup()
56
- expect(getByA11yRole('progressbar')).toBeTruthy()
57
- expect(
58
- getByA11yValue({ min: 0, max: 100, now: percentage, text: `${percentage}%` })
59
- ).toBeTruthy()
60
- })
61
-
62
- it('renders stacked progress bars', () => {
63
- const inactiveA11yLabel = 'This bar is inactive'
64
- const { getByA11yLabel } = setup({
65
- children: (
66
- <>
67
- <Progress.Bar
68
- percentage={percentage + 10}
69
- variant={{ inactive: true }}
70
- accessibilityLabel={inactiveA11yLabel}
71
- />
72
- <Progress.Bar percentage={percentage} accessibilityLabel={a11yLabel} />
73
- </>
74
- )
75
- })
76
- expect(within(getByA11yLabel(progressA11yLabel)).getByA11yLabel(inactiveA11yLabel)).toBeTruthy()
77
- expect(within(getByA11yLabel(progressA11yLabel)).getByA11yLabel(a11yLabel)).toBeTruthy()
78
- })
79
- })
@@ -1,87 +0,0 @@
1
- import React from 'react'
2
- import { fireEvent, render } from '@testing-library/react-native'
3
-
4
- import { Radio } from '../../src'
5
- import Theme from '../../__fixtures__/Theme'
6
-
7
- const checkedId = 'Radio-Checked'
8
- const inputId = 'Radio-Input'
9
- const setup = (props) =>
10
- render(
11
- <Theme>
12
- <Radio {...props} />
13
- </Theme>
14
- )
15
-
16
- describe('Radio', () => {
17
- it('renders with defaults', () => {
18
- const { getByRole } = setup()
19
-
20
- expect(getByRole('radio')).toBeTruthy()
21
- })
22
-
23
- it('renders the label', () => {
24
- const label = 'Test label message'
25
- const { queryByText } = setup({ label })
26
-
27
- expect(queryByText(label)).toBeTruthy()
28
- })
29
-
30
- it('renders error styling on validation failure', () => {
31
- const errorBorderColor = '#e12339' // from __fixtures__/testTheme.js
32
- const { getByTestId } = setup({ error: true })
33
-
34
- const radioInput = getByTestId(inputId)
35
- expect(radioInput).toHaveStyle({ borderColor: errorBorderColor })
36
- })
37
-
38
- it('triggers the callback', () => {
39
- const onChange = jest.fn()
40
-
41
- const { getByRole } = setup({ onChange })
42
-
43
- const radio = getByRole('radio')
44
- expect(onChange).not.toHaveBeenCalled()
45
- fireEvent(radio, 'press')
46
- expect(onChange).toHaveBeenCalledTimes(1)
47
- })
48
-
49
- it('cannot be changed if inactive', () => {
50
- const { getByRole, queryByTestId } = setup({ inactive: true })
51
-
52
- const radio = getByRole('radio')
53
- expect(queryByTestId(checkedId)).toBeFalsy()
54
- fireEvent(radio, 'press')
55
- expect(queryByTestId(checkedId)).toBeFalsy()
56
- })
57
-
58
- describe('when uncontrolled', () => {
59
- it('uses `defaultChecked` as the initial value', () => {
60
- const { queryByTestId } = setup({ defaultChecked: true })
61
-
62
- expect(queryByTestId(checkedId)).toBeTruthy()
63
- })
64
-
65
- it('changes value', () => {
66
- const { getByRole, queryByTestId } = setup({ defaultChecked: false })
67
-
68
- const radio = getByRole('radio')
69
- expect(queryByTestId(checkedId)).toBeFalsy()
70
- fireEvent(radio, 'press')
71
- expect(queryByTestId(checkedId)).toBeTruthy()
72
- })
73
- })
74
-
75
- describe('when controlled', () => {
76
- it('calls `onChange` with the new value', () => {
77
- const onChange = jest.fn()
78
- const { getByRole, queryByTestId } = setup({ onChange, checked: false })
79
-
80
- const radio = getByRole('radio')
81
- expect(queryByTestId(checkedId)).toBeFalsy()
82
- fireEvent(radio, 'press', { nativeEvent: 'example' })
83
- expect(onChange).toHaveBeenCalledTimes(1)
84
- expect(onChange).toHaveBeenCalledWith(true, { nativeEvent: 'example' })
85
- })
86
- })
87
- })