@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,514 +0,0 @@
1
- import React from 'react'
2
- import PropTypes from 'prop-types'
3
- import { renderHook } from '@testing-library/react-hooks'
4
-
5
- import ThemeProvider from '../../src/ThemeProvider'
6
- import { useThemeTokens, useThemeTokensCallback } from '../../src/ThemeProvider/useThemeTokens'
7
- import * as tokenUtils from '../../src/ThemeProvider/utils/theme-tokens'
8
-
9
- // Mock out the function that checks the theme version
10
- const validateThemeTokensVersion = jest.spyOn(tokenUtils, 'validateThemeTokensVersion')
11
- validateThemeTokensVersion.mockImplementation(() => undefined)
12
-
13
- const { doesThemeRuleApply, doesThemeConditionApply } = tokenUtils
14
-
15
- const componentName = 'TestComponent'
16
-
17
- const palette = {
18
- colours: {
19
- white: 'rgb(255,255,255)',
20
- red: 'rgb(255,0,0)',
21
- green: 'rgb(0,255,0)',
22
- blue: 'rgb(0,0,255)',
23
- pink: 'rgb(255,50,50)',
24
- lilac: 'rgb(255,200,255)',
25
- other: 'rgb(1,2,3)'
26
- },
27
- sizes: {
28
- none: 0,
29
- tight: 5,
30
- medium: 10,
31
- wide: 50,
32
- other: 999
33
- },
34
- opacities: {
35
- solid: 1,
36
- opaque: 0.9,
37
- cloudy: 0.8,
38
- translucent: 0.5,
39
- transparent: 0.1,
40
- invisible: 0
41
- }
42
- }
43
-
44
- const defaultTokens = {
45
- // TODO: replace `undefined`s here with appropriate "no thanks" values if this ADR lands
46
- // https://github.com/telus/universal-design-system/issues/526
47
- background: undefined,
48
- padding: palette.sizes.medium,
49
- opacity: palette.opacities.solid
50
- }
51
-
52
- const theme = {
53
- metadata: {
54
- name: 'tokens-test',
55
- themeTokensVersion: 'test-version'
56
- },
57
- components: {
58
- [componentName]: {
59
- appearances: {
60
- windowSize: {
61
- values: ['small', 'large'],
62
- type: 'context'
63
- },
64
- colour: {
65
- values: ['red', 'green', 'blue'],
66
- type: 'variant'
67
- },
68
- on: {
69
- values: [true, false],
70
- type: 'state'
71
- }
72
- },
73
- tokens: defaultTokens,
74
- rules: [
75
- { if: { windowSize: 'small' }, tokens: { padding: palette.sizes.tight } },
76
- { if: { windowSize: 'large' }, tokens: { padding: palette.sizes.wide } },
77
- { if: { colour: 'red' }, tokens: { background: palette.colours.red } },
78
- { if: { colour: 'green' }, tokens: { background: palette.colours.green } },
79
- { if: { colour: 'blue' }, tokens: { background: palette.colours.blue } },
80
-
81
- // Slightly translucent if green or blue
82
- { if: { colour: ['green', 'blue'] }, tokens: { opacity: palette.opacities.opaque } },
83
-
84
- // Make red slightly pink and translucent when large
85
- {
86
- if: { colour: 'red', windowSize: 'large' },
87
- tokens: { background: palette.colours.pink, opacity: palette.opacities.cloudy }
88
- },
89
-
90
- // Reset all colours to translucent white if "on"
91
- {
92
- if: { on: true },
93
- tokens: { background: palette.colours.white, opacity: palette.opacities.translucent }
94
- },
95
-
96
- // Make large "on" reds and blues slightly purple
97
- {
98
- if: { on: true, windowSize: 'large', colour: ['red', 'blue'] },
99
- tokens: { background: palette.colours.lilac }
100
- }
101
- ]
102
- }
103
- }
104
- }
105
-
106
- // Example of a component that is built on another component and applies its own rules.
107
- // For these tests we're only interested in rules it applies to its "inner" child component.
108
- theme.components.ExtendedComponent = {
109
- appearances: {
110
- innerOn: {
111
- description: 'ExtendedComponent is built on TestComponent with rules for when it is "on"',
112
- values: [true, false],
113
- type: 'state'
114
- }
115
- },
116
- tokens: {
117
- // Extending components may need to use different names to avoid namespace collisions
118
- innerColour: palette.colours.lilac
119
- },
120
- rules: [
121
- {
122
- // Make inner component text red when the inner component is on
123
- if: { innerOn: true },
124
- tokens: {
125
- innerColour: palette.colours.red
126
- }
127
- }
128
- ]
129
- }
130
-
131
- const ThemeWrapper = ({ children }) => (
132
- <ThemeProvider defaultTheme={theme}>{children}</ThemeProvider>
133
- )
134
- ThemeWrapper.propTypes = { children: PropTypes.node.isRequired }
135
-
136
- const getHookResult = (hookFn) => {
137
- const {
138
- result: { current }
139
- } = renderHook(hookFn, {
140
- wrapper: ThemeWrapper
141
- })
142
- return current
143
- }
144
-
145
- describe('useThemeTokens', () => {
146
- it('gives default tokens when no appearances are given', () => {
147
- const themeTokens = getHookResult(() => useThemeTokens(componentName))
148
-
149
- expect(themeTokens).toEqual(defaultTokens)
150
- })
151
-
152
- it('resolves simple rules for single appearances', () => {
153
- const red = getHookResult(() => useThemeTokens(componentName, {}, { colour: 'red' }, {}))
154
- const large = getHookResult(() =>
155
- useThemeTokens(componentName, {}, {}, { windowSize: 'large' })
156
- )
157
- const on = getHookResult(() => useThemeTokens(componentName, {}, {}, { on: true }))
158
-
159
- expect(red).toEqual({ ...defaultTokens, background: palette.colours.red })
160
- expect(large).toEqual({ ...defaultTokens, padding: palette.sizes.wide })
161
- expect(on).toEqual({
162
- ...defaultTokens,
163
- background: palette.colours.white,
164
- opacity: palette.opacities.translucent
165
- })
166
- })
167
-
168
- it('resolves rules which match multiple values from an array', () => {
169
- const blue = getHookResult(() => useThemeTokens(componentName, {}, { colour: 'blue' }, {}))
170
- const green = getHookResult(() => useThemeTokens(componentName, {}, { colour: 'green' }, {}))
171
-
172
- expect(green).toEqual({
173
- ...defaultTokens,
174
- background: palette.colours.green,
175
- opacity: palette.opacities.opaque
176
- })
177
- expect(blue).toEqual({
178
- ...defaultTokens,
179
- background: palette.colours.blue,
180
- opacity: palette.opacities.opaque
181
- })
182
- })
183
-
184
- it('resolves combinations and intersections of appearances', () => {
185
- const largeRed = getHookResult(() =>
186
- useThemeTokens(componentName, {}, { colour: 'red' }, { windowSize: 'large' })
187
- )
188
- const smallRed = getHookResult(() =>
189
- useThemeTokens(componentName, {}, { colour: 'red' }, { windowSize: 'small' })
190
- )
191
-
192
- const largeBlue = getHookResult(() =>
193
- useThemeTokens(componentName, {}, { colour: 'blue' }, { windowSize: 'large' })
194
- )
195
- const smallBlue = getHookResult(() =>
196
- useThemeTokens(componentName, {}, { colour: 'blue' }, { windowSize: 'small' })
197
- )
198
-
199
- // largeRed includes specific large-red intersection rule
200
- expect(largeRed).toEqual({
201
- opacity: palette.opacities.cloudy,
202
- padding: palette.sizes.wide,
203
- background: palette.colours.pink
204
- })
205
- expect(smallRed).toEqual({
206
- ...defaultTokens,
207
- padding: palette.sizes.tight,
208
- background: palette.colours.red
209
- })
210
-
211
- // includes blue + windowSize + blue-or-green rules
212
- expect(largeBlue).toEqual({
213
- opacity: palette.opacities.opaque,
214
- padding: palette.sizes.wide,
215
- background: palette.colours.blue
216
- })
217
- expect(smallBlue).toEqual({
218
- opacity: palette.opacities.opaque,
219
- padding: palette.sizes.tight,
220
- background: palette.colours.blue
221
- })
222
- })
223
-
224
- it('overrides earlier-defined rules with applicable later ones', () => {
225
- const greenOn = getHookResult(() =>
226
- useThemeTokens(componentName, {}, { colour: 'green' }, { on: true })
227
- )
228
- const largeGreenOn = getHookResult(() =>
229
- useThemeTokens(componentName, {}, { colour: 'green' }, { on: true, windowSize: 'large' })
230
- )
231
- const redOn = getHookResult(() =>
232
- useThemeTokens(componentName, {}, { colour: 'red' }, { on: true })
233
- )
234
- const largeRedOn = getHookResult(() =>
235
- useThemeTokens(componentName, {}, { colour: 'red' }, { on: true, windowSize: 'large' })
236
- )
237
-
238
- expect(greenOn).toEqual({
239
- padding: palette.sizes.medium,
240
- opacity: palette.opacities.translucent,
241
- background: palette.colours.white
242
- })
243
- expect(redOn).toEqual({
244
- padding: palette.sizes.medium,
245
- opacity: palette.opacities.translucent,
246
- background: palette.colours.white
247
- })
248
- expect(largeGreenOn).toEqual({
249
- padding: palette.sizes.wide,
250
- opacity: palette.opacities.translucent,
251
- background: palette.colours.white
252
- })
253
- expect(largeRedOn).toEqual({
254
- padding: palette.sizes.wide,
255
- opacity: palette.opacities.translucent,
256
- background: palette.colours.lilac
257
- })
258
- })
259
-
260
- it('overrides default theme tokens with passed-in tokens', () => {
261
- const greenPlusBackground = getHookResult(() =>
262
- useThemeTokens(componentName, { background: palette.colours.other }, { colour: 'green' }, {})
263
- )
264
- const largeRedPlusOpacity = getHookResult(() =>
265
- useThemeTokens(
266
- componentName,
267
- { opacity: palette.opacities.transparent },
268
- { colour: 'red' },
269
- { windowSize: 'large' }
270
- )
271
- )
272
- const largeBlueOnPlusTokens = getHookResult(() =>
273
- useThemeTokens(
274
- componentName,
275
- { padding: palette.sizes.other, background: palette.colours.other },
276
- { colour: 'blue' },
277
- { on: true, windowSize: 'large' }
278
- )
279
- )
280
-
281
- expect(greenPlusBackground).toEqual({
282
- ...defaultTokens,
283
- background: palette.colours.other,
284
- opacity: palette.opacities.opaque
285
- })
286
- expect(largeRedPlusOpacity).toEqual({
287
- opacity: palette.opacities.transparent,
288
- padding: palette.sizes.wide,
289
- background: palette.colours.pink
290
- })
291
- expect(largeBlueOnPlusTokens).toEqual({
292
- padding: palette.sizes.other,
293
- opacity: palette.opacities.translucent,
294
- background: palette.colours.other
295
- })
296
- })
297
-
298
- // Simulate a scenario where a parent component passes tokens to a child component.
299
- // Imagine a component that contains a button and wants to tell it what colour to be when pressed.
300
- it('overrides default theme tokens using passed-in tokens function', () => {
301
- // ExtendedComponent is a parent to TestComponent and passes it additional theming rules,
302
- // setting child TestComponent's colour to lilac when child's state is "off", and red when "on".
303
- const getTokensByExtendedRules = getHookResult(() =>
304
- useThemeTokensCallback('ExtendedComponent')
305
- )
306
-
307
- // If the extending component uses different naming to its inner component, we need to map names
308
- const selectInnerTokens = ({ innerColour }) => ({ colour: innerColour })
309
- const tokensFn = (innerAppearances) =>
310
- selectInnerTokens(getTokensByExtendedRules({ innerOn: innerAppearances.on }))
311
-
312
- const on = { on: true }
313
-
314
- // These lines reflect what happens inside TestComponent when it receives this tokens prop
315
- const onInnerTokens = getHookResult(() => useThemeTokens(componentName, tokensFn, {}, on))
316
- const offInnerTokens = getHookResult(() => useThemeTokens(componentName, tokensFn, {}, {}))
317
-
318
- expect(offInnerTokens).toEqual({
319
- ...defaultTokens,
320
- colour: palette.colours.lilac
321
- })
322
-
323
- const onDefaultTokens = getHookResult(() => useThemeTokens(componentName, {}, {}, on))
324
- expect(onInnerTokens).toEqual({
325
- ...onDefaultTokens,
326
- colour: palette.colours.red
327
- })
328
- })
329
-
330
- it('overrides default and resolved tokens with passed in defined-but-falsy values', () => {
331
- const unsetDefault = getHookResult(() =>
332
- useThemeTokens(componentName, { padding: null, background: null, opacity: null }, {}, {})
333
- )
334
- const zeroDefault = getHookResult(() =>
335
- useThemeTokens(
336
- componentName,
337
- { padding: palette.sizes.none, opacity: palette.opacities.invisible },
338
- {},
339
- {}
340
- )
341
- )
342
- const unsetLargeRedOn = getHookResult(() =>
343
- useThemeTokens(
344
- componentName,
345
- { padding: null, background: null, opacity: null },
346
- { colour: 'red' },
347
- { on: true, windowSize: 'large' }
348
- )
349
- )
350
- const zeroLargeRedOn = getHookResult(() =>
351
- useThemeTokens(
352
- componentName,
353
- { padding: palette.sizes.none, opacity: palette.opacities.invisible },
354
- { colour: 'red' },
355
- { on: true, windowSize: 'large' }
356
- )
357
- )
358
-
359
- expect(unsetDefault).toEqual({ padding: null, background: null, opacity: null })
360
- expect(zeroDefault).toEqual({
361
- ...defaultTokens,
362
- padding: palette.sizes.none,
363
- opacity: palette.opacities.invisible
364
- })
365
-
366
- expect(unsetLargeRedOn).toEqual({
367
- padding: null,
368
- background: null,
369
- opacity: null
370
- })
371
- expect(zeroLargeRedOn).toEqual({
372
- background: palette.colours.lilac,
373
- padding: palette.sizes.none,
374
- opacity: palette.opacities.invisible
375
- })
376
- })
377
-
378
- it('does not unset default and resolved tokens with passed in explicit undefined', () => {
379
- const undefinedDefault = getHookResult(() =>
380
- useThemeTokens(
381
- componentName,
382
- { padding: undefined, background: undefined, opacity: undefined },
383
- {},
384
- {}
385
- )
386
- )
387
- expect(undefinedDefault).toEqual(defaultTokens)
388
- })
389
-
390
- // Catch-all test to check every combination
391
- // More readable spaced like a table
392
- /* prettier-ignore */
393
- const everyAppearance = [
394
- [{ colour: undefined }, { windowSize: undefined, on: undefined }],
395
- [{ colour: undefined }, { windowSize: 'small', on: undefined }],
396
- [{ colour: undefined }, { windowSize: 'large', on: undefined }],
397
- [{ colour: 'red' }, { windowSize: undefined, on: undefined }],
398
- [{ colour: 'red' }, { windowSize: 'small', on: undefined }],
399
- [{ colour: 'red' }, { windowSize: 'large', on: undefined }],
400
- [{ colour: 'green' }, { windowSize: undefined, on: undefined }],
401
- [{ colour: 'green' }, { windowSize: 'small', on: undefined }],
402
- [{ colour: 'green' }, { windowSize: 'large', on: undefined }],
403
- [{ colour: 'blue' }, { windowSize: undefined, on: undefined }],
404
- [{ colour: 'blue' }, { windowSize: 'small', on: undefined }],
405
- [{ colour: 'blue' }, { windowSize: 'large', on: undefined }],
406
-
407
- [{ colour: undefined }, { windowSize: undefined, on: true }],
408
- [{ colour: undefined }, { windowSize: 'small', on: true }],
409
- [{ colour: undefined }, { windowSize: 'large', on: true }],
410
- [{ colour: 'red' }, { windowSize: undefined, on: true }],
411
- [{ colour: 'red' }, { windowSize: 'small', on: true }],
412
- [{ colour: 'red' }, { windowSize: 'large', on: true }],
413
- [{ colour: 'green' }, { windowSize: undefined, on: true }],
414
- [{ colour: 'green' }, { windowSize: 'small', on: true }],
415
- [{ colour: 'green' }, { windowSize: 'large', on: true }],
416
- [{ colour: 'blue' }, { windowSize: undefined, on: true }],
417
- [{ colour: 'blue' }, { windowSize: 'small', on: true }],
418
- [{ colour: 'blue' }, { windowSize: 'large', on: true }]
419
- ].map((arr, index) => [...arr, index])
420
-
421
- // More readable spaced like a table
422
- /* prettier-ignore */
423
- const expectedTokens = [
424
- { background: undefined, padding: palette.sizes.medium, opacity: palette.opacities.solid },
425
- { background: undefined, padding: palette.sizes.tight, opacity: palette.opacities.solid },
426
- { background: undefined, padding: palette.sizes.wide, opacity: palette.opacities.solid },
427
- { background: palette.colours.red, padding: palette.sizes.medium, opacity: palette.opacities.solid },
428
- { background: palette.colours.red, padding: palette.sizes.tight, opacity: palette.opacities.solid },
429
- { background: palette.colours.pink, padding: palette.sizes.wide, opacity: palette.opacities.cloudy },
430
- { background: palette.colours.green, padding: palette.sizes.medium, opacity: palette.opacities.opaque },
431
- { background: palette.colours.green, padding: palette.sizes.tight, opacity: palette.opacities.opaque },
432
- { background: palette.colours.green, padding: palette.sizes.wide, opacity: palette.opacities.opaque },
433
- { background: palette.colours.blue, padding: palette.sizes.medium, opacity: palette.opacities.opaque },
434
- { background: palette.colours.blue, padding: palette.sizes.tight, opacity: palette.opacities.opaque },
435
- { background: palette.colours.blue, padding: palette.sizes.wide, opacity: palette.opacities.opaque },
436
-
437
- { background: palette.colours.white, padding: palette.sizes.medium, opacity: palette.opacities.translucent },
438
- { background: palette.colours.white, padding: palette.sizes.tight, opacity: palette.opacities.translucent },
439
- { background: palette.colours.white, padding: palette.sizes.wide, opacity: palette.opacities.translucent },
440
- { background: palette.colours.white, padding: palette.sizes.medium, opacity: palette.opacities.translucent },
441
- { background: palette.colours.white, padding: palette.sizes.tight, opacity: palette.opacities.translucent },
442
- { background: palette.colours.lilac, padding: palette.sizes.wide, opacity: palette.opacities.translucent },
443
- { background: palette.colours.white, padding: palette.sizes.medium, opacity: palette.opacities.translucent },
444
- { background: palette.colours.white, padding: palette.sizes.tight, opacity: palette.opacities.translucent },
445
- { background: palette.colours.white, padding: palette.sizes.wide, opacity: palette.opacities.translucent },
446
- { background: palette.colours.white, padding: palette.sizes.medium, opacity: palette.opacities.translucent },
447
- { background: palette.colours.white, padding: palette.sizes.tight, opacity: palette.opacities.translucent },
448
- { background: palette.colours.lilac, padding: palette.sizes.wide, opacity: palette.opacities.translucent }
449
- ]
450
- it.each(everyAppearance)('resolves variant: %p state: %p index: %p', (variant, state, index) => {
451
- const themeTokens = getHookResult(() => useThemeTokens(componentName, {}, variant, state))
452
-
453
- expect(themeTokens).toEqual(expectedTokens[index])
454
- })
455
- })
456
-
457
- describe('useThemeTokens doesConditionApply', () => {
458
- const values = { a: 'A', b: 1, c: false }
459
- it('returns true if value is a match', () => {
460
- expect(doesThemeConditionApply(['a', 'A'], values)).toBe(true)
461
- expect(doesThemeConditionApply(['b', 1], values)).toBe(true)
462
- expect(doesThemeConditionApply(['c', false], values)).toBe(true)
463
- })
464
- it('returns false if value is not a match', () => {
465
- expect(doesThemeConditionApply(['a', false], values)).toBe(false)
466
- expect(doesThemeConditionApply(['b', 'A'], values)).toBe(false)
467
- expect(doesThemeConditionApply(['c', 1], values)).toBe(false)
468
- })
469
- it('returns true if value is an array containing a match', () => {
470
- expect(doesThemeConditionApply(['a', [9, true, 'A', '']], values)).toBe(true)
471
- expect(doesThemeConditionApply(['b', ['', 1, 'B', true]], values)).toBe(true)
472
- expect(doesThemeConditionApply(['c', [false, 'C', true, 0]], values)).toBe(true)
473
- })
474
- it('returns false if value is an array not containing a match', () => {
475
- expect(doesThemeConditionApply(['a', [9, true, 'B', '']], values)).toBe(false)
476
- expect(doesThemeConditionApply(['b', ['', 2, 'B', true]], values)).toBe(false)
477
- expect(doesThemeConditionApply(['c', [null, 'C', true, 0]], values)).toBe(false)
478
- })
479
-
480
- it('returns false if appearance value is missing and rule specifies a not-null value', () => {
481
- expect(doesThemeConditionApply(['a', 'something'], { a: undefined })).toBe(false)
482
- expect(doesThemeConditionApply(['a', 'something'], { a: null })).toBe(false)
483
- expect(doesThemeConditionApply(['a', ['something', 'else']], { a: undefined })).toBe(false)
484
- expect(doesThemeConditionApply(['a', ['something', 'else']], { a: null })).toBe(false)
485
- })
486
-
487
- it('returns true if appearance value is nullish and rule value is null', () => {
488
- expect(doesThemeConditionApply(['a', null], { a: undefined })).toBe(true)
489
- expect(doesThemeConditionApply(['a', null], { a: null })).toBe(true)
490
- expect(doesThemeConditionApply(['a', [null], 'else'], { a: undefined })).toBe(true)
491
- expect(doesThemeConditionApply(['a', [null, 'else']], { a: null })).toBe(true)
492
- })
493
- })
494
-
495
- describe('useThemeTokens doesRuleApply', () => {
496
- const values = { a: 'A', b: 1, c: false }
497
- it('returns true if every provided singular condition is an exact match', () => {
498
- expect(doesThemeRuleApply({ if: { a: 'A' } }, values)).toBe(true)
499
- expect(doesThemeRuleApply({ if: { b: 1, a: 'A' } }, values)).toBe(true)
500
- expect(doesThemeRuleApply({ if: { c: false, b: 1, a: 'A' } }, values)).toBe(true)
501
- })
502
- it('returns true if every provided singular condition is a match including arrays containing a match', () => {
503
- expect(doesThemeRuleApply({ if: { a: ['A', 'B'] } }, values)).toBe(true)
504
- expect(doesThemeRuleApply({ if: { b: [1, 2, 3, 4, 5], a: 'A' } }, values)).toBe(true)
505
- expect(doesThemeRuleApply({ if: { c: [0, false], b: [1, 2], a: ['A', 'B'] } }, values)).toBe(
506
- true
507
- )
508
- })
509
- it('returns false if any provided condition is not a match', () => {
510
- expect(doesThemeRuleApply({ if: { a: 'A', b: 2 } }, values)).toBe(false)
511
- expect(doesThemeRuleApply({ if: { b: 1, a: ['a', 'b', 'c'] } }, values)).toBe(false)
512
- expect(doesThemeRuleApply({ if: { c: true, b: 1, a: 'A' } }, values)).toBe(false)
513
- })
514
- })
@@ -1,41 +0,0 @@
1
- import pkg from '../../../package.json'
2
- import { validateThemeTokensVersion } from '../../../src/ThemeProvider/utils/theme-tokens'
3
-
4
- function validate({ expectedVersion, actualVersion }) {
5
- pkg.dependencies['@telus-uds/system-theme-tokens'] = expectedVersion
6
- const theme = {
7
- metadata: {
8
- themeTokensVersion: actualVersion
9
- }
10
- }
11
- validateThemeTokensVersion(theme)
12
- }
13
-
14
- describe('validateThemeTokensVersion', () => {
15
- test('No error on matching version', async () => {
16
- const expectedVersion = '1.2.3'
17
- const actualVersion = '1.2.3'
18
-
19
- validate({ expectedVersion, actualVersion })
20
-
21
- // No errors, no problem...
22
- })
23
-
24
- test('Throws if theme version is old', async () => {
25
- const expectedVersion = '^2.3.4'
26
- const actualVersion = '2.3.3'
27
-
28
- expect(() => validate({ expectedVersion, actualVersion })).toThrow(
29
- 'Invalid UDS token schema version detected.'
30
- )
31
- })
32
-
33
- test('Throws if theme version is new', async () => {
34
- const expectedVersion = '^1.2.3'
35
- const actualVersion = '2.3.4'
36
-
37
- expect(() => validate({ expectedVersion, actualVersion })).toThrow(
38
- 'Invalid UDS token schema version detected.'
39
- )
40
- })
41
- })
@@ -1,82 +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 ToggleSwitch from '../../src/ToggleSwitch/ToggleSwitch'
6
-
7
- const checked = { checked: true }
8
-
9
- describe('ToggleSwitch', () => {
10
- it('is accessible as a switch by default', async () => {
11
- const { queryAllByA11yRole } = render(
12
- <Theme>
13
- <ToggleSwitch />
14
- </Theme>
15
- )
16
- expect(queryAllByA11yRole('button')).toHaveLength(0)
17
- expect(queryAllByA11yRole('switch')).toHaveLength(1)
18
- })
19
-
20
- it('selects when pressed', async () => {
21
- const { getByA11yRole, queryAllByA11yState } = render(
22
- <Theme>
23
- <ToggleSwitch />
24
- </Theme>
25
- )
26
- const toggleSwitch = getByA11yRole('switch')
27
- expect(queryAllByA11yState(checked)).toHaveLength(0)
28
- await fireEvent.press(toggleSwitch)
29
- expect(queryAllByA11yState(checked)).toHaveLength(1)
30
- })
31
-
32
- it('applies an initialValue as on and deselects when unpressed', async () => {
33
- const { getByA11yRole, queryAllByA11yState } = render(
34
- <Theme>
35
- <ToggleSwitch initialValue={true} />
36
- </Theme>
37
- )
38
- const toggleSwitch = getByA11yRole('switch')
39
- expect(queryAllByA11yState(checked)).toHaveLength(1)
40
- await fireEvent.press(toggleSwitch)
41
- expect(queryAllByA11yState(checked)).toHaveLength(0)
42
- })
43
-
44
- it("doesn't select when pressed when inactive", async () => {
45
- const { getByA11yRole, queryAllByA11yState } = render(
46
- <Theme>
47
- <ToggleSwitch inactive />
48
- </Theme>
49
- )
50
- const toggleSwitch = getByA11yRole('switch')
51
- expect(queryAllByA11yState(checked)).toHaveLength(0)
52
- await fireEvent.press(toggleSwitch)
53
- expect(queryAllByA11yState(checked)).toHaveLength(0)
54
- })
55
-
56
- it("calls onChange with new value and doesn't change own state when passed a value", async () => {
57
- const handleChange = jest.fn((arg) => arg)
58
- const { getByA11yRole, queryAllByA11yState } = render(
59
- <Theme>
60
- <ToggleSwitch value={false} onChange={handleChange} />
61
- </Theme>
62
- )
63
- expect(handleChange).toHaveBeenCalledTimes(0)
64
- const toggleSwitch = getByA11yRole('switch')
65
- expect(queryAllByA11yState(checked)).toHaveLength(0)
66
-
67
- await fireEvent(toggleSwitch, 'press', { nativeEvent: 'example' })
68
- expect(handleChange).toHaveBeenCalledTimes(1)
69
- expect(handleChange).toHaveBeenLastCalledWith(true, { nativeEvent: 'example' })
70
- expect(queryAllByA11yState(checked)).toHaveLength(0)
71
- })
72
-
73
- it('displays the label', () => {
74
- const label = 'Toggle me!'
75
- const { getByText } = render(
76
- <Theme>
77
- <ToggleSwitch label={label} />
78
- </Theme>
79
- )
80
- expect(getByText(label)).toBeTruthy()
81
- })
82
- })