@nypl/design-system-react-components 0.25.3 → 0.25.7

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 (135) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +47 -11
  3. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +4 -0
  4. package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +1 -0
  5. package/dist/components/Button/Button.d.ts +9 -6
  6. package/dist/components/Button/ButtonTypes.d.ts +2 -1
  7. package/dist/components/Card/Card.d.ts +0 -25
  8. package/dist/components/Icons/IconSvgs.d.ts +3 -0
  9. package/dist/components/Icons/IconTypes.d.ts +3 -0
  10. package/dist/components/Notification/Notification.d.ts +6 -4
  11. package/dist/components/ProgressIndicator/ProgressIndicator.d.ts +29 -0
  12. package/dist/components/ProgressIndicator/ProgressIndicatorTypes.d.ts +8 -0
  13. package/dist/components/SearchBar/SearchBar.d.ts +3 -3
  14. package/dist/components/Slider/Slider.d.ts +57 -0
  15. package/dist/components/Tabs/Tabs.d.ts +1 -1
  16. package/dist/components/TextInput/TextInput.d.ts +6 -0
  17. package/dist/design-system-react-components.cjs.development.js +1022 -455
  18. package/dist/design-system-react-components.cjs.development.js.map +1 -1
  19. package/dist/design-system-react-components.cjs.production.min.js +1 -1
  20. package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
  21. package/dist/design-system-react-components.esm.js +1015 -444
  22. package/dist/design-system-react-components.esm.js.map +1 -1
  23. package/dist/index.d.ts +8 -3
  24. package/dist/resources.scss +180 -170
  25. package/dist/styles.css +1 -1
  26. package/dist/theme/components/breadcrumb.d.ts +9 -0
  27. package/dist/theme/components/button.d.ts +10 -0
  28. package/dist/theme/components/progressIndicator.d.ts +50 -0
  29. package/dist/theme/components/slider.d.ts +51 -0
  30. package/dist/theme/foundations/breakpoints.d.ts +8 -8
  31. package/dist/theme/foundations/global.d.ts +6 -1
  32. package/package.json +71 -83
  33. package/src/__tests__/setup.ts +2 -2
  34. package/src/components/Accordion/Accordion.stories.mdx +30 -34
  35. package/src/components/Autosuggest/Autosuggest.stories.mdx +3 -3
  36. package/src/components/Autosuggest/Autosuggest.stories.tsx +1 -0
  37. package/src/components/Autosuggest/_Autosuggest.scss +5 -5
  38. package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +24 -8
  39. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +33 -0
  40. package/src/components/Breadcrumbs/Breadcrumbs.tsx +5 -1
  41. package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +1 -0
  42. package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +297 -1
  43. package/src/components/Button/Button.stories.mdx +8 -6
  44. package/src/components/Button/Button.test.tsx +20 -0
  45. package/src/components/Button/Button.tsx +14 -23
  46. package/src/components/Button/ButtonTypes.tsx +1 -0
  47. package/src/components/Button/__snapshots__/Button.test.tsx.snap +29 -4
  48. package/src/components/Card/Card.stories.mdx +1 -1
  49. package/src/components/Card/Card.tsx +3 -3
  50. package/src/components/CardEdition/CardEdition.stories.tsx +15 -47
  51. package/src/components/CardEdition/_CardEdition.scss +22 -23
  52. package/src/components/Chakra/Box.stories.mdx +14 -15
  53. package/src/components/Chakra/Center.stories.mdx +15 -8
  54. package/src/components/Chakra/Grid.stories.mdx +16 -7
  55. package/src/components/Chakra/Stack.stories.mdx +35 -18
  56. package/src/components/DatePicker/DatePicker.test.tsx +31 -30
  57. package/src/components/DatePicker/DatePicker.tsx +7 -4
  58. package/src/components/DatePicker/_DatePicker.scss +4 -4
  59. package/src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap +19 -5
  60. package/src/components/Form/Form.stories.mdx +4 -5
  61. package/src/components/Grid/SimpleGrid.stories.mdx +1 -0
  62. package/src/components/Hero/HeroTypes.tsx +1 -0
  63. package/src/components/HorizontalRule/HorizontalRule.stories.mdx +2 -3
  64. package/src/components/Icons/Icon.stories.mdx +2 -3
  65. package/src/components/Icons/IconSvgs.tsx +6 -0
  66. package/src/components/Icons/IconTypes.tsx +3 -0
  67. package/src/components/Image/Image.stories.mdx +2 -3
  68. package/src/components/Input/Input.stories.tsx +20 -64
  69. package/src/components/Input/_Input.scss +23 -14
  70. package/src/components/Modal/Modal.stories.mdx +3 -3
  71. package/src/components/Modal/_Modal.scss +2 -2
  72. package/src/components/Notification/Notification.stories.mdx +1 -1
  73. package/src/components/Notification/Notification.tsx +13 -4
  74. package/src/components/Pagination/Pagination.stories.mdx +3 -2
  75. package/src/components/Pagination/Pagination.stories.tsx +1 -2
  76. package/src/components/ProgressIndicator/ProgressIndicator.stories.mdx +292 -0
  77. package/src/components/ProgressIndicator/ProgressIndicator.test.tsx +225 -0
  78. package/src/components/ProgressIndicator/ProgressIndicator.tsx +126 -0
  79. package/src/components/ProgressIndicator/ProgressIndicatorTypes.ts +8 -0
  80. package/src/components/ProgressIndicator/__snapshots__/ProgressIndicator.test.tsx.snap +357 -0
  81. package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +3 -0
  82. package/src/components/RadioGroup/RadioGroup.stories.mdx +2 -3
  83. package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +4 -0
  84. package/src/components/SearchBar/SearchBar.Test.tsx +66 -21
  85. package/src/components/SearchBar/SearchBar.stories.mdx +110 -11
  86. package/src/components/SearchBar/SearchBar.tsx +15 -5
  87. package/src/components/Select/SelectTypes.tsx +1 -0
  88. package/src/components/Slider/Slider.stories.mdx +529 -0
  89. package/src/components/Slider/Slider.test.tsx +653 -0
  90. package/src/components/Slider/Slider.tsx +303 -0
  91. package/src/components/Slider/__snapshots__/Slider.test.tsx.snap +1946 -0
  92. package/src/components/StyleGuide/Bidirectionality.stories.mdx +1 -1
  93. package/src/components/StyleGuide/Breakpoints.stories.mdx +21 -7
  94. package/src/components/StyleGuide/Buttons.stories.mdx +9 -2
  95. package/src/components/StyleGuide/DesignTokens.stories.mdx +170 -0
  96. package/src/components/Tabs/Tabs.tsx +5 -5
  97. package/src/components/Template/Template.stories.mdx +6 -6
  98. package/src/components/TextInput/TextInput.stories.mdx +1 -1
  99. package/src/components/TextInput/TextInput.tsx +15 -2
  100. package/src/components/TextInput/TextInputTypes.tsx +2 -0
  101. package/src/components/VideoPlayer/VideoPlayer.stories.mdx +2 -3
  102. package/src/docs/Chakra.stories.mdx +2 -2
  103. package/src/index.ts +12 -6
  104. package/src/resources.scss +5 -5
  105. package/src/styles/base/{_02-breakpoints.scss → _01-breakpoints.scss} +9 -10
  106. package/src/styles/base/{_03-mixins.scss → _02-mixins.scss} +16 -5
  107. package/src/styles/base/{_04-base.scss → _03-base.scss} +7 -2
  108. package/src/styles/base/{_05-focus.scss → _04-focus.scss} +0 -15
  109. package/src/styles/base/_place-holder.scss +14 -3
  110. package/src/styles/{03-space → space}/_space-inline.scss +14 -14
  111. package/src/styles/{03-space → space}/_space-inset.scss +10 -10
  112. package/src/styles/space/_space-stack.scss +116 -0
  113. package/src/styles.scss +13 -44
  114. package/src/theme/components/breadcrumb.ts +10 -0
  115. package/src/theme/components/button.ts +10 -2
  116. package/src/theme/components/card.ts +11 -9
  117. package/src/theme/components/datePicker.ts +1 -1
  118. package/src/theme/components/list.ts +2 -2
  119. package/src/theme/components/notification.ts +5 -3
  120. package/src/theme/components/progressIndicator.ts +62 -0
  121. package/src/theme/components/skeletonLoader.ts +1 -1
  122. package/src/theme/components/slider.ts +79 -0
  123. package/src/theme/foundations/breakpoints.ts +8 -8
  124. package/src/theme/foundations/global.ts +6 -1
  125. package/src/theme/index.ts +4 -0
  126. package/src/utils/componentCategories.ts +3 -3
  127. package/src/styles/01-colors/_colors-brand.scss +0 -62
  128. package/src/styles/01-colors/_colors-utility.scss +0 -67
  129. package/src/styles/02-typography/_type-scale.css +0 -11
  130. package/src/styles/02-typography/_type-weight.css +0 -7
  131. package/src/styles/02-typography/_typefaces.css +0 -4
  132. package/src/styles/03-space/_space-stack.scss +0 -116
  133. package/src/styles/03-space/_space.css +0 -30
  134. package/src/styles/base/_card-grid.scss +0 -77
  135. package/src/styles/base/_typography.scss +0 -11
@@ -0,0 +1,653 @@
1
+ import * as React from "react";
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import { axe } from "jest-axe";
4
+ import renderer from "react-test-renderer";
5
+
6
+ import Slider from "./Slider";
7
+
8
+ describe("Slider Accessibility", () => {
9
+ describe("Single Slider", () => {
10
+ it("passes axe accessibility test", async () => {
11
+ const { container } = render(
12
+ <Slider
13
+ defaultValue={50}
14
+ helperText="Component helper text."
15
+ invalidText="Component error text :("
16
+ labelText="Label"
17
+ />
18
+ );
19
+ expect(await axe(container)).toHaveNoViolations();
20
+ });
21
+ it("passes axe accessibility test without a label", async () => {
22
+ const { container } = render(
23
+ <Slider
24
+ defaultValue={50}
25
+ helperText="Component helper text."
26
+ invalidText="Component error text :("
27
+ labelText="Label"
28
+ showLabel={false}
29
+ />
30
+ );
31
+ expect(await axe(container)).toHaveNoViolations();
32
+ });
33
+ it("passes axe accessibility test without visible values", async () => {
34
+ const { container } = render(
35
+ <Slider
36
+ defaultValue={50}
37
+ helperText="Component helper text."
38
+ invalidText="Component error text :("
39
+ labelText="Label"
40
+ showValues={false}
41
+ showBoxes={false}
42
+ />
43
+ );
44
+ expect(await axe(container)).toHaveNoViolations();
45
+ });
46
+ });
47
+
48
+ describe("Range Slider", () => {
49
+ it("passes axe accessibility test", async () => {
50
+ const { container } = render(
51
+ <Slider
52
+ defaultValue={[25, 75]}
53
+ helperText="Component helper text."
54
+ invalidText="Component error text :("
55
+ labelText="Label"
56
+ isRangeSlider
57
+ />
58
+ );
59
+ expect(await axe(container)).toHaveNoViolations();
60
+ });
61
+ it("passes axe accessibility test without a label", async () => {
62
+ const { container } = render(
63
+ <Slider
64
+ defaultValue={[25, 75]}
65
+ helperText="Component helper text."
66
+ invalidText="Component error text :("
67
+ labelText="Label"
68
+ showLabel={false}
69
+ isRangeSlider
70
+ />
71
+ );
72
+ expect(await axe(container)).toHaveNoViolations();
73
+ });
74
+ it("passes axe accessibility test without visible values", async () => {
75
+ const { container } = render(
76
+ <Slider
77
+ defaultValue={[25, 75]}
78
+ helperText="Component helper text."
79
+ invalidText="Component error text :("
80
+ labelText="Label"
81
+ showValues={false}
82
+ showBoxes={false}
83
+ isRangeSlider
84
+ />
85
+ );
86
+ expect(await axe(container)).toHaveNoViolations();
87
+ });
88
+ });
89
+ });
90
+
91
+ describe("Slider", () => {
92
+ describe("Single Slider", () => {
93
+ it("renders a label, two static values, text input, and helper text", () => {
94
+ render(
95
+ <Slider
96
+ defaultValue={50}
97
+ helperText="Component helper text."
98
+ invalidText="Component error text :("
99
+ labelText="Label"
100
+ />
101
+ );
102
+ expect(screen.getByText(/Label/i)).toBeInTheDocument();
103
+ expect(screen.getByText(/Optional/i)).toBeInTheDocument();
104
+ expect(screen.getByRole("slider")).toBeInTheDocument();
105
+ // default min and max values
106
+ expect(screen.getByText("0")).toBeInTheDocument();
107
+ expect(screen.getByText("100")).toBeInTheDocument();
108
+ // Default value; this is the role in the slider context.
109
+ expect(screen.getByRole("spinbutton")).toHaveValue(50);
110
+ expect(screen.getByText("Component helper text.")).toBeInTheDocument();
111
+ });
112
+
113
+ it("adds the appropriate aria-* attributes to the slider element", () => {
114
+ render(
115
+ <Slider
116
+ id="sliderId"
117
+ defaultValue={50}
118
+ helperText="Component helper text."
119
+ invalidText="Component error text :("
120
+ labelText="Label"
121
+ />
122
+ );
123
+ const slider = screen.getByRole("slider");
124
+
125
+ expect(slider).toHaveAttribute("aria-valuemin", "0");
126
+ expect(slider).toHaveAttribute("aria-valuemax", "100");
127
+ expect(slider).toHaveAttribute("aria-valuenow", "50");
128
+ expect(slider).toHaveAttribute("aria-labelledBy", "sliderId-label");
129
+ });
130
+
131
+ it("renders the 'required' text in the label or hides it", () => {
132
+ const { rerender } = render(
133
+ <Slider
134
+ defaultValue={50}
135
+ helperText="Component helper text."
136
+ invalidText="Component error text :("
137
+ labelText="Label"
138
+ />
139
+ );
140
+ // "Optional" by default.
141
+ expect(screen.getByText(/Optional/i)).toBeInTheDocument();
142
+
143
+ rerender(
144
+ <Slider
145
+ defaultValue={50}
146
+ helperText="Component helper text."
147
+ invalidText="Component error text :("
148
+ labelText="Label"
149
+ isRequired
150
+ />
151
+ );
152
+ expect(screen.queryByText(/Optional/i)).not.toBeInTheDocument();
153
+ expect(screen.getByText(/Required/i)).toBeInTheDocument();
154
+
155
+ rerender(
156
+ <Slider
157
+ defaultValue={50}
158
+ helperText="Component helper text."
159
+ invalidText="Component error text :("
160
+ labelText="Label"
161
+ isRequired
162
+ optReqFlag={false}
163
+ />
164
+ );
165
+ expect(screen.queryByText(/Optional/i)).not.toBeInTheDocument();
166
+ expect(screen.queryByText(/Required/i)).not.toBeInTheDocument();
167
+ });
168
+
169
+ it("hides the label but adds it as an aria-label attribute", () => {
170
+ render(
171
+ <Slider
172
+ defaultValue={50}
173
+ helperText="Component helper text."
174
+ invalidText="Component error text :("
175
+ labelText="Label"
176
+ showLabel={false}
177
+ />
178
+ );
179
+
180
+ expect(screen.queryByText(/Label/i)).not.toBeInTheDocument();
181
+ expect(screen.getByRole("slider")).toHaveAttribute("aria-label", "Label");
182
+ });
183
+
184
+ it("hides the min/max static values", () => {
185
+ const { rerender } = render(
186
+ <Slider
187
+ defaultValue={50}
188
+ helperText="Component helper text."
189
+ invalidText="Component error text :("
190
+ labelText="Label"
191
+ min={25}
192
+ max={75}
193
+ />
194
+ );
195
+ expect(screen.getByText("25")).toBeInTheDocument();
196
+ expect(screen.getByText("75")).toBeInTheDocument();
197
+
198
+ rerender(
199
+ <Slider
200
+ defaultValue={50}
201
+ helperText="Component helper text."
202
+ invalidText="Component error text :("
203
+ labelText="Label"
204
+ min={25}
205
+ max={75}
206
+ showValues={false}
207
+ />
208
+ );
209
+ expect(screen.queryByText("25")).not.toBeInTheDocument();
210
+ expect(screen.queryByText("75")).not.toBeInTheDocument();
211
+ });
212
+
213
+ it("hides the current value input box", () => {
214
+ const { rerender } = render(
215
+ <Slider
216
+ defaultValue={50}
217
+ helperText="Component helper text."
218
+ invalidText="Component error text :("
219
+ labelText="Label"
220
+ />
221
+ );
222
+ expect(screen.getByRole("spinbutton")).toBeInTheDocument();
223
+ expect(screen.getByRole("spinbutton")).toHaveValue(50);
224
+
225
+ rerender(
226
+ <Slider
227
+ defaultValue={50}
228
+ helperText="Component helper text."
229
+ invalidText="Component error text :("
230
+ labelText="Label"
231
+ showBoxes={false}
232
+ />
233
+ );
234
+ expect(screen.queryByRole("spinbutton")).not.toBeInTheDocument();
235
+ });
236
+
237
+ it("renders the invalid state", () => {
238
+ render(
239
+ <Slider
240
+ defaultValue={50}
241
+ helperText="Component helper text."
242
+ invalidText="Component error text :("
243
+ labelText="Label"
244
+ isInvalid
245
+ />
246
+ );
247
+
248
+ expect(
249
+ screen.queryByText("Component helper text")
250
+ ).not.toBeInTheDocument();
251
+ expect(screen.getByText("Component error text :(")).toBeInTheDocument();
252
+ expect(screen.getByRole("spinbutton")).toHaveAttribute(
253
+ "aria-invalid",
254
+ "true"
255
+ );
256
+ });
257
+
258
+ it("renders the disabled state", () => {
259
+ render(
260
+ <Slider
261
+ defaultValue={50}
262
+ helperText="Component helper text."
263
+ invalidText="Component error text :("
264
+ labelText="Label"
265
+ isDisabled
266
+ />
267
+ );
268
+ expect(screen.getByRole("slider")).toHaveAttribute(
269
+ "aria-disabled",
270
+ "true"
271
+ );
272
+ });
273
+
274
+ it("updates the value through the text input", () => {
275
+ render(
276
+ <Slider
277
+ defaultValue={50}
278
+ helperText="Component helper text."
279
+ invalidText="Component error text :("
280
+ labelText="Label"
281
+ />
282
+ );
283
+ const input = screen.getByRole("spinbutton");
284
+ fireEvent.change(input, {
285
+ target: { value: "42" },
286
+ });
287
+ expect(input).toHaveValue(42);
288
+
289
+ // The max value is 100, so an entered value higher than 100 will
290
+ // be set to 100.
291
+ fireEvent.change(input, {
292
+ target: { value: "12345" },
293
+ });
294
+ expect(input).toHaveValue(100);
295
+ });
296
+
297
+ it("gets the current value through the onChange callback function", () => {
298
+ let currentValue = 0;
299
+ function onChange(value) {
300
+ currentValue = value;
301
+ }
302
+
303
+ render(
304
+ <Slider
305
+ defaultValue={50}
306
+ helperText="Component helper text."
307
+ invalidText="Component error text :("
308
+ labelText="Label"
309
+ onChange={onChange}
310
+ />
311
+ );
312
+
313
+ const input = screen.getByRole("spinbutton");
314
+ fireEvent.change(input, {
315
+ target: { value: "42" },
316
+ });
317
+ expect(currentValue).toEqual(42);
318
+
319
+ fireEvent.change(input, {
320
+ target: { value: "84" },
321
+ });
322
+ expect(currentValue).toEqual(84);
323
+ });
324
+
325
+ it("renders the UI snapshot correctly", () => {
326
+ const defaultSlider = renderer
327
+ .create(
328
+ <Slider
329
+ id="defaultSlider"
330
+ defaultValue={50}
331
+ helperText="Component helper text."
332
+ invalidText="Component error text :("
333
+ labelText="Label"
334
+ />
335
+ )
336
+ .toJSON();
337
+ const errored = renderer
338
+ .create(
339
+ <Slider
340
+ id="errored"
341
+ defaultValue={50}
342
+ helperText="Component helper text."
343
+ invalidText="Component error text :("
344
+ labelText="Label"
345
+ isInvalid
346
+ />
347
+ )
348
+ .toJSON();
349
+ const required = renderer
350
+ .create(
351
+ <Slider
352
+ id="required"
353
+ defaultValue={50}
354
+ helperText="Component helper text."
355
+ invalidText="Component error text :("
356
+ labelText="Label"
357
+ isRequired
358
+ />
359
+ )
360
+ .toJSON();
361
+ const disabled = renderer
362
+ .create(
363
+ <Slider
364
+ id="disabled"
365
+ defaultValue={50}
366
+ helperText="Component helper text."
367
+ invalidText="Component error text :("
368
+ labelText="Label"
369
+ isDisabled
370
+ />
371
+ )
372
+ .toJSON();
373
+ const noLabels = renderer
374
+ .create(
375
+ <Slider
376
+ id="noLabels"
377
+ defaultValue={50}
378
+ helperText="Component helper text."
379
+ invalidText="Component error text :("
380
+ labelText="Label"
381
+ showLabel={false}
382
+ showHelperInvalidText={false}
383
+ />
384
+ )
385
+ .toJSON();
386
+ const noVisibleValues = renderer
387
+ .create(
388
+ <Slider
389
+ id="noVisibleValues"
390
+ defaultValue={50}
391
+ helperText="Component helper text."
392
+ invalidText="Component error text :("
393
+ labelText="Label"
394
+ showValues={false}
395
+ showBoxes={false}
396
+ />
397
+ )
398
+ .toJSON();
399
+ const onlySlider = renderer
400
+ .create(
401
+ <Slider
402
+ id="onlySlider"
403
+ defaultValue={50}
404
+ helperText="Component helper text."
405
+ invalidText="Component error text :("
406
+ labelText="Label"
407
+ showLabel={false}
408
+ showHelperInvalidText={false}
409
+ showValues={false}
410
+ showBoxes={false}
411
+ />
412
+ )
413
+ .toJSON();
414
+
415
+ expect(defaultSlider).toMatchSnapshot();
416
+ expect(errored).toMatchSnapshot();
417
+ expect(required).toMatchSnapshot();
418
+ expect(disabled).toMatchSnapshot();
419
+ expect(noLabels).toMatchSnapshot();
420
+ expect(noVisibleValues).toMatchSnapshot();
421
+ expect(onlySlider).toMatchSnapshot();
422
+ });
423
+ });
424
+
425
+ describe("Range Slider", () => {
426
+ it("renders everything from the single but also two text input fields", () => {
427
+ render(
428
+ <Slider
429
+ defaultValue={[25, 75]}
430
+ helperText="Component helper text."
431
+ invalidText="Component error text :("
432
+ labelText="Label"
433
+ isRangeSlider
434
+ />
435
+ );
436
+ expect(screen.getByText(/Label/i)).toBeInTheDocument();
437
+ expect(screen.getByText(/Optional/i)).toBeInTheDocument();
438
+ // The range slider has two sliders!
439
+ expect(screen.getAllByRole("slider")).toHaveLength(2);
440
+ // default min and max values
441
+ expect(screen.getByText("0")).toBeInTheDocument();
442
+ expect(screen.getByText("100")).toBeInTheDocument();
443
+ // The range slider has two text inputs.
444
+ expect(screen.getAllByRole("spinbutton")).toHaveLength(2);
445
+ expect(screen.getAllByRole("spinbutton")[0]).toHaveValue(25);
446
+ expect(screen.getAllByRole("spinbutton")[1]).toHaveValue(75);
447
+ expect(screen.getByText("Component helper text.")).toBeInTheDocument();
448
+ });
449
+
450
+ it("adds the appropriate aria-* attributes to the slider element", () => {
451
+ render(
452
+ <Slider
453
+ id="sliderId"
454
+ defaultValue={[25, 75]}
455
+ helperText="Component helper text."
456
+ invalidText="Component error text :("
457
+ labelText="Label"
458
+ isRangeSlider
459
+ />
460
+ );
461
+ const slider = screen.getAllByRole("slider");
462
+
463
+ expect(slider[0]).toHaveAttribute("aria-valuemin", "0");
464
+ // This is set so the starting thumb can't go past the current end value.
465
+ expect(slider[0]).toHaveAttribute("aria-valuemax", "75");
466
+ expect(slider[0]).toHaveAttribute("aria-valuenow", "25");
467
+ expect(slider[0]).toHaveAttribute("aria-labelledBy", "sliderId-label");
468
+ // This is set so the ending thumb can't go below the current start value.
469
+ expect(slider[1]).toHaveAttribute("aria-valuemin", "25");
470
+ expect(slider[1]).toHaveAttribute("aria-valuemax", "100");
471
+ expect(slider[1]).toHaveAttribute("aria-valuenow", "75");
472
+ expect(slider[1]).toHaveAttribute("aria-labelledBy", "sliderId-label");
473
+ });
474
+
475
+ it("hides the label but adds it as an aria-label attribute", () => {
476
+ render(
477
+ <Slider
478
+ defaultValue={[25, 75]}
479
+ helperText="Component helper text."
480
+ invalidText="Component error text :("
481
+ labelText="Custom Label"
482
+ isRangeSlider
483
+ showLabel={false}
484
+ />
485
+ );
486
+
487
+ expect(screen.queryByText(/Label/i)).not.toBeInTheDocument();
488
+ expect(screen.getAllByRole("slider")[0]).toHaveAttribute(
489
+ "aria-label",
490
+ "Custom Label - start value"
491
+ );
492
+ expect(screen.getAllByRole("slider")[1]).toHaveAttribute(
493
+ "aria-label",
494
+ "Custom Label - end value"
495
+ );
496
+ });
497
+
498
+ it("renders the invalid state if the start and end values are wrong", () => {
499
+ // The start value is bigger than the end value.
500
+ render(
501
+ <Slider
502
+ defaultValue={[75, 25]}
503
+ helperText="Component helper text."
504
+ invalidText="Component error text :("
505
+ labelText="Label"
506
+ isRangeSlider
507
+ />
508
+ );
509
+
510
+ expect(
511
+ screen.queryByText("Component helper text")
512
+ ).not.toBeInTheDocument();
513
+ expect(screen.getByText("Component error text :(")).toBeInTheDocument();
514
+ expect(screen.getAllByRole("spinbutton")[0]).toHaveAttribute(
515
+ "aria-invalid",
516
+ "true"
517
+ );
518
+ expect(screen.getAllByRole("spinbutton")[1]).toHaveAttribute(
519
+ "aria-invalid",
520
+ "true"
521
+ );
522
+ });
523
+
524
+ it("updates the value through the text input", () => {
525
+ render(
526
+ <Slider
527
+ defaultValue={[25, 75]}
528
+ helperText="Component helper text."
529
+ invalidText="Component error text :("
530
+ labelText="Label"
531
+ isRangeSlider
532
+ />
533
+ );
534
+ const startingInput = screen.getAllByRole("spinbutton")[0];
535
+ const endingInput = screen.getAllByRole("spinbutton")[1];
536
+ fireEvent.change(startingInput, {
537
+ target: { value: "42" },
538
+ });
539
+ fireEvent.change(endingInput, {
540
+ target: { value: "79" },
541
+ });
542
+
543
+ expect(startingInput).toHaveValue(42);
544
+ expect(endingInput).toHaveValue(79);
545
+ });
546
+
547
+ it("renders the UI snapshot correctly", () => {
548
+ const defaultRangeSlider = renderer
549
+ .create(
550
+ <Slider
551
+ id="defaultRangeSlider"
552
+ defaultValue={[25, 75]}
553
+ helperText="Component helper text."
554
+ invalidText="Component error text :("
555
+ labelText="Label"
556
+ isRangeSlider
557
+ />
558
+ )
559
+ .toJSON();
560
+ const errored = renderer
561
+ .create(
562
+ <Slider
563
+ id="errored"
564
+ defaultValue={[25, 75]}
565
+ helperText="Component helper text."
566
+ invalidText="Component error text :("
567
+ labelText="Label"
568
+ isRangeSlider
569
+ isInvalid
570
+ />
571
+ )
572
+ .toJSON();
573
+ const required = renderer
574
+ .create(
575
+ <Slider
576
+ id="required"
577
+ defaultValue={[25, 75]}
578
+ helperText="Component helper text."
579
+ invalidText="Component error text :("
580
+ labelText="Label"
581
+ isRangeSlider
582
+ isRequired
583
+ />
584
+ )
585
+ .toJSON();
586
+ const disabled = renderer
587
+ .create(
588
+ <Slider
589
+ id="disabled"
590
+ defaultValue={[25, 75]}
591
+ helperText="Component helper text."
592
+ invalidText="Component error text :("
593
+ labelText="Label"
594
+ isRangeSlider
595
+ isDisabled
596
+ />
597
+ )
598
+ .toJSON();
599
+ const noLabels = renderer
600
+ .create(
601
+ <Slider
602
+ id="noLabels"
603
+ defaultValue={[25, 75]}
604
+ helperText="Component helper text."
605
+ invalidText="Component error text :("
606
+ labelText="Label"
607
+ isRangeSlider
608
+ showLabel={false}
609
+ showHelperInvalidText={false}
610
+ />
611
+ )
612
+ .toJSON();
613
+ const noVisibleValues = renderer
614
+ .create(
615
+ <Slider
616
+ id="noVisibleValues"
617
+ defaultValue={[25, 75]}
618
+ helperText="Component helper text."
619
+ invalidText="Component error text :("
620
+ labelText="Label"
621
+ isRangeSlider
622
+ showValues={false}
623
+ showBoxes={false}
624
+ />
625
+ )
626
+ .toJSON();
627
+ const onlySlider = renderer
628
+ .create(
629
+ <Slider
630
+ id="onlySlider"
631
+ defaultValue={[25, 75]}
632
+ helperText="Component helper text."
633
+ invalidText="Component error text :("
634
+ labelText="Label"
635
+ isRangeSlider
636
+ showLabel={false}
637
+ showHelperInvalidText={false}
638
+ showValues={false}
639
+ showBoxes={false}
640
+ />
641
+ )
642
+ .toJSON();
643
+
644
+ expect(defaultRangeSlider).toMatchSnapshot();
645
+ expect(errored).toMatchSnapshot();
646
+ expect(required).toMatchSnapshot();
647
+ expect(disabled).toMatchSnapshot();
648
+ expect(noLabels).toMatchSnapshot();
649
+ expect(noVisibleValues).toMatchSnapshot();
650
+ expect(onlySlider).toMatchSnapshot();
651
+ });
652
+ });
653
+ });