bright-components 10.1.1 → 10.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. package/dist/components/DayPicker/NewDayPicker/index.js +207 -0
  2. package/dist/components/DayPicker/index.js +30 -7
  3. package/dist/components/DayPickerPanel/index.js +1 -1
  4. package/dist/components/Icons/Users/index.js +1 -1
  5. package/dist/components/Icons/Visibility/index.js +2 -14
  6. package/dist/components/Icons/Visible/index.js +29 -0
  7. package/dist/components/Modal/ModalBody/index.js +1 -0
  8. package/dist/components/Modal/index.js +2 -1
  9. package/dist/components/Time/TimePicker/index.js +1 -0
  10. package/dist/setupTests.js +5 -0
  11. package/package.json +3 -2
  12. package/src/components/DayPicker/NewDayPicker/index.js +208 -0
  13. package/src/components/DayPicker/examples.md +17 -0
  14. package/src/components/DayPicker/index.js +43 -17
  15. package/src/components/DayPicker/test.js +297 -1
  16. package/src/components/DayPickerPanel/index.js +1 -1
  17. package/src/components/DayPickerPanel/test.js +1 -1
  18. package/src/components/DurationInput/test.js +5 -3
  19. package/src/components/EmployeePicker/FilterBar/test.js +1 -1
  20. package/src/components/Icons/Users/index.js +1 -1
  21. package/src/components/Icons/Visibility/index.js +3 -14
  22. package/src/components/Icons/Visible/examples.md +5 -0
  23. package/src/components/Icons/Visible/index.js +19 -0
  24. package/src/components/Modal/ModalBody/index.js +1 -0
  25. package/src/components/Modal/index.js +2 -1
  26. package/src/components/Modal/test.js +0 -1
  27. package/src/components/ResponsiveTabs/test.js +3 -3
  28. package/src/components/Time/TimePicker/index.js +1 -0
  29. package/src/components/Time/TimePicker/test.js +29 -28
  30. package/src/setupTests.js +2 -0
@@ -231,3 +231,20 @@ initialState={dates: {from: new Date(2018, 3, 1), to: undefined}};
231
231
  isDateSelect={true}
232
232
  />
233
233
  ```
234
+ Day Picker - typeable
235
+ ```js
236
+ initialState={dates: {from: new Date(2018, 3, 1), to: undefined}};
237
+ <DayPicker
238
+ range={state.dates}
239
+ yearRange={{ min: 2000, max: 2030}}
240
+ style={{
241
+ width: '70%'
242
+ }}
243
+ GA={{
244
+ category: 'Test',
245
+ actionId: 'Test'
246
+ }}
247
+ onSelectedDate={dates=>setState({dates})}
248
+ typeable
249
+ />
250
+ ```
@@ -26,6 +26,8 @@ import breakpoints from 'constants/breakpoints';
26
26
 
27
27
  import CalendarIcon from 'components/Icons/Calendar/';
28
28
 
29
+ import NewDayPicker from './NewDayPicker';
30
+
29
31
  const friendlyShort = 'EEE dd MMM';
30
32
  const friendlyShortWithYear = 'EEE dd MMM yyyy';
31
33
 
@@ -232,11 +234,12 @@ class DayPicker extends React.Component {
232
234
  panelAbsoluteOnDesktop,
233
235
  onSelectedDate,
234
236
  isDateSelect,
237
+ typeable,
235
238
  ...rest
236
239
  } = this.props;
237
240
 
238
241
  const { dayPickerOpen } = this.state;
239
- const { range } = this.props;
242
+ const { range, locale } = this.props;
240
243
 
241
244
  const fromDate = range.from
242
245
  ? format(range.from, this.getDisplayFormat())
@@ -250,20 +253,39 @@ class DayPicker extends React.Component {
250
253
 
251
254
  return (
252
255
  <DayPickerInputContainer {...rest}>
253
- <InputBox
254
- onClick={this.toggleDayPicker}
255
- error={error}
256
- disabled={disabled}
257
- legacyInputStyle={legacyInputStyle}
258
- data-testid="input-selector"
259
- >
260
- {datesToDisplay ? (
261
- <span>{datesToDisplay}</span>
262
- ) : (
263
- <Placeholder>{placeholder}</Placeholder>
264
- )}
265
- <OpenCalendarIcon size={22} disabled={disabled} />
266
- </InputBox>
256
+ {!typeable || dateRange ? (
257
+ <InputBox
258
+ onClick={this.toggleDayPicker}
259
+ error={error}
260
+ disabled={disabled}
261
+ legacyInputStyle={legacyInputStyle}
262
+ data-testid="input-selector"
263
+ >
264
+ {datesToDisplay ? (
265
+ <span>{datesToDisplay}</span>
266
+ ) : (
267
+ <Placeholder>{placeholder}</Placeholder>
268
+ )}
269
+ <OpenCalendarIcon size={22} disabled={disabled} />
270
+ </InputBox>
271
+ ) : (
272
+ <NewDayPicker
273
+ placeholder={placeholder}
274
+ datesToDisplay={datesToDisplay}
275
+ range={range}
276
+ allowClear={allowClear}
277
+ yearRange={yearRange}
278
+ onSelectedDate={onSelectedDate}
279
+ locale={locale}
280
+ clearValue={this.clearValue}
281
+ disabled={disabled}
282
+ error={error}
283
+ toggleDayPicker={this.toggleDayPicker}
284
+ GA={GA}
285
+ recordValue={recordValue}
286
+ dayPickerOpen={dayPickerOpen}
287
+ />
288
+ )}
267
289
 
268
290
  {dayPickerOpen && (
269
291
  <DayRangeContainer
@@ -330,7 +352,9 @@ DayPicker.propTypes = {
330
352
  legacyInputStyle: bool,
331
353
  closeButton: bool,
332
354
  panelAbsoluteOnDesktop: bool,
333
- isDateSelect: bool
355
+ isDateSelect: bool,
356
+ typeable: bool,
357
+ locale: string
334
358
  };
335
359
 
336
360
  DayPicker.defaultProps = {
@@ -356,7 +380,9 @@ DayPicker.defaultProps = {
356
380
  legacyInputStyle: false,
357
381
  closeButton: false,
358
382
  panelAbsoluteOnDesktop: true,
359
- isDateSelect: false
383
+ isDateSelect: false,
384
+ typeable: false,
385
+ locale: 'GB'
360
386
  };
361
387
 
362
388
  export { DayPicker as Unwrapped };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { render, fireEvent } from '@testing-library/react';
2
+ import { render, fireEvent, wait } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
3
4
  import ReactGA from 'react-ga';
4
5
  import DayPicker from '.';
5
6
 
@@ -406,4 +407,299 @@ describe('<DayPicker />', () => {
406
407
  expect(ReactGA.event).toHaveBeenCalledTimes(1);
407
408
  });
408
409
  });
410
+
411
+ describe('Typing date', () => {
412
+ it('should set the correct date when typed in', async () => {
413
+ wrapper.rerender(
414
+ <DayPicker
415
+ {...props}
416
+ typeable
417
+ dateRange={false}
418
+ yearRange={{ min: 2000, max: 2100 }}
419
+ GA={{
420
+ category: undefined,
421
+ actionId: undefined
422
+ }}
423
+ />
424
+ );
425
+ const inputSelect = wrapper.getByTestId('new input');
426
+
427
+ fireEvent.focus(inputSelect);
428
+ userEvent.type(inputSelect, `010203`);
429
+ await wait(() => expect(inputSelect.value).toEqual('01/02/03'));
430
+ fireEvent.blur(inputSelect);
431
+
432
+ expect(onMockSelectedDate).toHaveBeenLastCalledWith({
433
+ from: new Date('2003-02-01T00:00:00.000Z'),
434
+ to: new Date('2003-02-01T00:00:00.000Z')
435
+ });
436
+ });
437
+
438
+ it('should set the correct date when typed in - CA', () => {
439
+ wrapper.rerender(
440
+ <DayPicker
441
+ {...props}
442
+ typeable
443
+ dateRange={false}
444
+ yearRange={{ min: 2000, max: 2100 }}
445
+ locale="CA"
446
+ />
447
+ );
448
+ const inputSelect = wrapper.getByTestId('new input');
449
+
450
+ fireEvent.focus(inputSelect);
451
+ userEvent.type(inputSelect, '010203');
452
+ fireEvent.blur(inputSelect);
453
+
454
+ expect(onMockSelectedDate).toHaveBeenLastCalledWith({
455
+ from: new Date('2001-02-03T00:00:00.000Z'),
456
+ to: new Date('2001-02-03T00:00:00.000Z')
457
+ });
458
+ });
459
+
460
+ it('should show the correct date when date pre set', () => {
461
+ wrapper.rerender(
462
+ <DayPicker
463
+ {...props}
464
+ typeable
465
+ dateRange={false}
466
+ yearRange={{ min: 2000, max: 2100 }}
467
+ range={{
468
+ from: new Date('2019-08-01'),
469
+ to: undefined
470
+ }}
471
+ />
472
+ );
473
+ const inputSelect = wrapper.getByTestId('new input');
474
+
475
+ fireEvent.focus(inputSelect);
476
+
477
+ expect(inputSelect.value).toEqual('01/08/19');
478
+ });
479
+
480
+ it('should show the correct date when date pre set - CA', () => {
481
+ wrapper.rerender(
482
+ <DayPicker
483
+ {...props}
484
+ typeable
485
+ dateRange={false}
486
+ yearRange={{ min: 2000, max: 2100 }}
487
+ range={{
488
+ from: new Date('2019-08-01'),
489
+ to: undefined
490
+ }}
491
+ locale="CA"
492
+ />
493
+ );
494
+ const inputSelect = wrapper.getByTestId('new input');
495
+
496
+ fireEvent.focus(inputSelect);
497
+
498
+ expect(inputSelect.value).toEqual('19/08/01');
499
+ });
500
+
501
+ it('should allow clearing date', () => {
502
+ wrapper.rerender(
503
+ <DayPicker
504
+ {...props}
505
+ typeable
506
+ dateRange={false}
507
+ yearRange={{ min: 2000, max: 2100 }}
508
+ range={{
509
+ from: new Date('2019-08-01'),
510
+ to: undefined
511
+ }}
512
+ />
513
+ );
514
+ const inputSelect = wrapper.getByTestId('new input');
515
+
516
+ fireEvent.focus(inputSelect);
517
+ userEvent.type(inputSelect, '{selectall}{backspace}');
518
+ fireEvent.blur(inputSelect);
519
+
520
+ expect(onMockSelectedDate).toHaveBeenLastCalledWith({
521
+ from: undefined,
522
+ to: undefined
523
+ });
524
+ });
525
+
526
+ it('shouldnt save invalid dates', () => {
527
+ wrapper.rerender(
528
+ <DayPicker
529
+ {...props}
530
+ typeable
531
+ dateRange={false}
532
+ yearRange={{ min: 2000, max: 2100 }}
533
+ range={{
534
+ from: new Date('2019-08-01'),
535
+ to: undefined
536
+ }}
537
+ />
538
+ );
539
+ const inputSelect = wrapper.getByTestId('new input');
540
+
541
+ fireEvent.focus(inputSelect);
542
+ fireEvent.blur(inputSelect);
543
+ fireEvent.focus(inputSelect);
544
+ userEvent.type(inputSelect, '{selectall}{backspace}0101');
545
+ fireEvent.blur(inputSelect);
546
+
547
+ expect(onMockSelectedDate).toHaveBeenLastCalledWith('');
548
+ expect(wrapper.getByText('Date is invalid')).toBeInTheDocument();
549
+ });
550
+
551
+ it('shouldnt save dates outside the range', () => {
552
+ wrapper.rerender(
553
+ <DayPicker
554
+ {...props}
555
+ typeable
556
+ dateRange={false}
557
+ yearRange={{ min: 2018, max: 2030 }}
558
+ range={{
559
+ from: new Date('2019-08-01'),
560
+ to: undefined
561
+ }}
562
+ allowClear={false}
563
+ />
564
+ );
565
+ const inputSelect = wrapper.getByTestId('new input');
566
+
567
+ fireEvent.focus(inputSelect);
568
+ userEvent.type(inputSelect, '{selectall}{backspace}010131');
569
+ fireEvent.blur(inputSelect);
570
+
571
+ expect(onMockSelectedDate).toHaveBeenLastCalledWith({
572
+ from: new Date('2019-08-01T00:00:00.000Z'),
573
+ to: undefined
574
+ });
575
+ expect(
576
+ wrapper.getByText(
577
+ 'Year is outside of range. Must be between 2018 - 2030'
578
+ )
579
+ ).toBeInTheDocument();
580
+ });
581
+
582
+ it('should revert invalid date to empty if no initial date', () => {
583
+ onMockSelectedDate.mockClear();
584
+ wrapper.rerender(
585
+ <DayPicker
586
+ {...props}
587
+ typeable
588
+ dateRange={false}
589
+ yearRange={{ min: 2000, max: 2100 }}
590
+ range={{
591
+ from: undefined,
592
+ to: undefined
593
+ }}
594
+ allowClear={false}
595
+ />
596
+ );
597
+ const inputSelect = wrapper.getByTestId('new input');
598
+
599
+ fireEvent.focus(inputSelect);
600
+ fireEvent.blur(inputSelect);
601
+ fireEvent.focus(inputSelect);
602
+ userEvent.type(inputSelect, '{selectall}{backspace}0101');
603
+ fireEvent.blur(inputSelect);
604
+
605
+ expect(onMockSelectedDate).not.toHaveBeenCalled();
606
+ });
607
+
608
+ it('backspace / automatically', () => {
609
+ wrapper.rerender(
610
+ <DayPicker
611
+ {...props}
612
+ typeable
613
+ dateRange={false}
614
+ yearRange={{ min: 2000, max: 2100 }}
615
+ range={{
616
+ from: new Date('2019-08-01'),
617
+ to: undefined
618
+ }}
619
+ />
620
+ );
621
+ const inputSelect = wrapper.getByTestId('new input');
622
+
623
+ fireEvent.focus(inputSelect);
624
+ userEvent.type(inputSelect, `{backspace}{backspace}/`);
625
+ expect(inputSelect.value).toEqual('01/08/');
626
+ });
627
+
628
+ it('should open calendar view with the icon', () => {
629
+ wrapper.rerender(
630
+ <DayPicker
631
+ {...props}
632
+ typeable
633
+ dateRange={false}
634
+ yearRange={{ min: 2000, max: 2100 }}
635
+ range={{
636
+ from: new Date('2019-08-01'),
637
+ to: undefined
638
+ }}
639
+ />
640
+ );
641
+
642
+ fireEvent.click(wrapper.getByTestId('calendarIcon'));
643
+ expect(wrapper.getByTestId('daypicker-panel')).toBeInTheDocument();
644
+
645
+ const inputSelect = wrapper.getByTestId('new input');
646
+ fireEvent.focus(inputSelect);
647
+ fireEvent.blur(inputSelect);
648
+
649
+ expect(
650
+ wrapper.queryByTestId('daypicker-panel')
651
+ ).not.toBeInTheDocument();
652
+ });
653
+
654
+ it('should apply the error styling if error', () => {
655
+ wrapper.rerender(
656
+ <DayPicker {...props} dateRange={false} typeable error />
657
+ );
658
+
659
+ const inputSelect = wrapper.getByTestId('input-selector');
660
+ expect(inputSelect).toHaveStyleRule(
661
+ 'border-color',
662
+ '#FF5000 !important'
663
+ );
664
+ });
665
+
666
+ it('should apply the error styling if disabled', () => {
667
+ wrapper.rerender(
668
+ <DayPicker {...props} typeable dateRange={false} disabled />
669
+ );
670
+
671
+ const inputSelect = wrapper.getByTestId('new input');
672
+ expect(inputSelect).toBeDisabled();
673
+ });
674
+
675
+ it('should call the correct GA tags when the date is typed', async () => {
676
+ wrapper.rerender(
677
+ <DayPicker
678
+ {...props}
679
+ typeable
680
+ dateRange={false}
681
+ range={{
682
+ from: undefined,
683
+ to: undefined
684
+ }}
685
+ recordValue
686
+ />
687
+ );
688
+ expect(ReactGA.event).toHaveBeenCalledTimes(0);
689
+
690
+ const inputSelect = wrapper.getByTestId('new input');
691
+ fireEvent.focus(inputSelect);
692
+ userEvent.type(inputSelect, `201222`);
693
+ await wait(() => expect(inputSelect.value).toEqual('20/12/22'));
694
+ fireEvent.blur(inputSelect);
695
+
696
+ await wait(() =>
697
+ expect(ReactGA.event).toHaveBeenCalledWith({
698
+ action: 'ActionID - Set via Typing',
699
+ category: 'Test',
700
+ label: 'Tue 20 Dec 2022'
701
+ })
702
+ );
703
+ });
704
+ });
409
705
  });
@@ -178,7 +178,7 @@ class DayPickerPanel extends React.Component {
178
178
  range: { from, to }
179
179
  } = this.state;
180
180
 
181
- const actionEvent = selectedDay ? 'Set' : 'Apply';
181
+ const actionEvent = selectedDay ? 'Set via Date Picker' : 'Apply';
182
182
 
183
183
  if (category) {
184
184
  const label = dateRange
@@ -73,7 +73,7 @@ describe('Month Year and Calendar view', () => {
73
73
 
74
74
  expect(event).toHaveBeenCalledWith({
75
75
  category: 'Cat',
76
- action: 'Action ID - Set',
76
+ action: 'Action ID - Set via Date Picker',
77
77
  label: 'Tue 03 Apr 2018'
78
78
  });
79
79
  });
@@ -20,7 +20,7 @@ describe('<DurationInput />', () => {
20
20
  });
21
21
 
22
22
  it('should select a new days value when the days input is changed', () => {
23
- const daysInput = wrapper.getByRole('textbox');
23
+ const daysInput = wrapper.getByRole('spinbutton');
24
24
 
25
25
  expect(onChange).not.toHaveBeenCalled();
26
26
 
@@ -36,7 +36,7 @@ describe('<DurationInput />', () => {
36
36
  const blurProps = { ...props, onBlur: jest.fn() };
37
37
  wrapper.rerender(<DurationInput {...blurProps} />);
38
38
 
39
- const daysInput = wrapper.getByRole('textbox');
39
+ const daysInput = wrapper.getByRole('spinbutton');
40
40
  fireEvent.blur(daysInput);
41
41
 
42
42
  expect(blurProps.onBlur).toHaveBeenCalled();
@@ -54,7 +54,9 @@ describe('<DurationInput />', () => {
54
54
  });
55
55
 
56
56
  it('should select a new hours value and a new minutes value when the inputs are changed', () => {
57
- const [hoursInput, minutesInput] = wrapper.getAllByRole('textbox');
57
+ const [hoursInput, minutesInput] = wrapper.getAllByRole(
58
+ 'spinbutton'
59
+ );
58
60
 
59
61
  expect(onChange).not.toHaveBeenCalled();
60
62
 
@@ -33,7 +33,7 @@ describe('EmployeePickerFilterBar', () => {
33
33
  });
34
34
 
35
35
  const getInput = () => element.getByPlaceholderText('Enter name');
36
- const getSelect = () => element.getByRole('listbox');
36
+ const getSelect = () => element.getByRole('combobox');
37
37
 
38
38
  it('should call updateType when the user selects a filter type', () => {
39
39
  const input = getInput();
@@ -4,7 +4,7 @@ import IconBase from 'react-icon-base';
4
4
 
5
5
  const UsersIcon = props => (
6
6
  <IconBase viewBox="0 0 32 32" {...props}>
7
- <path d="M28.465 13.771A8.125 8.125 0 1 0 15.859 3.626 9.963 9.963 0 0 0 11.25 2.5c-5.522 0-10 4.478-10 10 0 2.7 1.071 5.148 2.81 6.946A10.945 10.945 0 0 0 0 27.963v1.844c0 1.206.986 2.192 2.192 2.192h18.115a2.198 2.198 0 0 0 2.192-2.192v-1.844c0-1.444-.284-2.824-.796-4.089h8.796c.825 0 1.5-.675 1.5-1.5v-2.25c0-2.671-1.416-5.025-3.535-6.354zM22.625 3c2.826 0 5.125 2.299 5.125 5.125s-2.299 5.125-5.125 5.125c-.483 0-.949-.069-1.391-.194a9.966 9.966 0 0 0-2.945-7.657A5.125 5.125 0 0 1 22.625 3zM11.25 5.5c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.14-7-7 3.14-7 7-7zM19.5 29H3v-1.036a7.96 7.96 0 0 1 3.56-6.631 9.96 9.96 0 0 0 4.69 1.168 9.958 9.958 0 0 0 4.685-1.165 8.16 8.16 0 0 1 1.224 1.006 7.903 7.903 0 0 1 2.341 5.621v1.038zm9.5-8.125h-9.117c-.44-.516-.925-.991-1.451-1.419.95-.981 1.7-2.156 2.188-3.459a8.12 8.12 0 0 0 4.86-.264 4.493 4.493 0 0 1 2.199 1.215 4.465 4.465 0 0 1 1.325 3.175v.751h-.003z" />
7
+ <path d="M6.421 16.496C6.15 15.635 6 14.773 6 14c0-3.308 2.692-6 6-6 1.069 0 2.073.283 2.944.775A6 6 0 0120 6c3.308 0 6 2.692 6 6 0 .773-.15 1.635-.421 2.496C28.166 15.525 30 18.051 30 21c0 1.654-1.346 3-3 3h-5.172A3.004 3.004 0 0119 26H5c-1.654 0-3-1.346-3-3 0-2.949 1.834-5.475 4.421-6.504zM8 14c0 2.479 2.069 6 4 6s4-3.521 4-6c0-2.206-1.794-4-4-4s-4 1.794-4 4zm12-6a4 4 0 00-3.49 2.05A5.974 5.974 0 0118 14c0 .773-.15 1.635-.421 2.496a7 7 0 012.315 1.506L20 18c1.931 0 4-3.521 4-6 0-2.206-1.794-4-4-4zm8 13a5.006 5.006 0 00-3.194-4.66 9.92 9.92 0 01-.43.737c-.903 1.402-1.995 2.331-3.156 2.717A6.93 6.93 0 0121.927 22H27c.551 0 1-.449 1-1zM5 24h14c.551 0 1-.449 1-1a5.006 5.006 0 00-3.194-4.66 9.92 9.92 0 01-.43.737C15.162 20.962 13.608 22 12 22c-1.608 0-3.162-1.038-4.376-2.923a10.13 10.13 0 01-.43-.737A5.006 5.006 0 004 23c0 .551.449 1 1 1z" />
8
8
  </IconBase>
9
9
  );
10
10
 
@@ -1,29 +1,18 @@
1
1
  import React from 'react';
2
- import { string, number } from 'prop-types';
2
+ import { number } from 'prop-types';
3
3
  import IconBase from 'react-icon-base';
4
4
 
5
5
  const VisibilityIcon = props => (
6
- <IconBase viewBox="0 0 256 256" {...props}>
7
- <path
8
- d="M254.89 122.97c-.36-.78-9.08-19.38-29.04-37.79C207.48 68.22 175.58 48 128 48S48.52 68.22 30.14 85.18c-19.95 18.41-28.67 37-29.04 37.79a12.026 12.026 0 0 0 0 10.06c.36.78 9.08 19.38 29.04 37.79C48.52 187.78 80.42 208 128 208s79.48-20.22 97.86-37.18c19.95-18.41 28.67-37 29.04-37.79 1.47-3.19 1.47-6.87-.01-10.06zM184 128c0 30.88-25.12 56-56 56s-56-25.12-56-56 25.12-56 56-56 56 25.12 56 56zm-158.3 0c3.54-5.84 10.5-15.91 21.44-25.84 2.49-2.26 5.05-4.39 7.68-6.4C50.44 105.63 48 116.53 48 128s2.44 22.37 6.81 32.24c-2.62-2.01-5.18-4.14-7.68-6.4-10.93-9.93-17.9-20-21.43-25.84zm183.17 25.84a118.32 118.32 0 0 1-7.68 6.4c4.36-9.87 6.81-20.77 6.81-32.24s-2.44-22.37-6.81-32.24c2.62 2.01 5.18 4.14 7.68 6.4 10.94 9.93 17.91 20.01 21.44 25.83-3.54 5.85-10.51 15.92-21.44 25.85z"
9
- fill={props.color}
10
- />
11
- <circle cx="128" cy="128" r="30" fill={props.color} />
12
- <path
13
- d="M252.49 3.51c-4.69-4.69-12.29-4.69-16.97 0l-232 232c-4.69 4.69-4.69 12.28 0 16.97 4.69 4.69 12.29 4.69 16.97 0l232-232c4.68-4.68 4.68-12.28 0-16.97z"
14
- fill={props.color}
15
- />
6
+ <IconBase viewBox="0 0 32 32" {...props}>
7
+ <path d="M29.769 15.36C29.519 15.06 23.562 8 16 8c-1.938 0-3.77.464-5.427 1.159L5.707 4.293a1 1 0 00-1.414 1.414l4.38 4.38c-3.774 2.108-6.282 5.08-6.442 5.274a1 1 0 000 1.278C2.481 16.94 8.438 24 16 24c1.938 0 3.77-.463 5.427-1.158l4.866 4.866a1 1 0 001.414-1.414l-4.38-4.38c3.774-2.108 6.282-5.081 6.442-5.274a1 1 0 000-1.278zM16 22c-5.372 0-10.05-4.336-11.647-6 .973-1.014 3.088-3.015 5.805-4.428l.25.25a6 6 0 007.77 7.77l1.699 1.699C18.653 21.727 17.349 22 16 22zm5.842-1.572l-9.719-9.719C13.347 10.274 14.651 10 16 10c5.372 0 10.049 4.335 11.647 6-.973 1.014-3.088 3.015-5.805 4.428z" />
16
8
  </IconBase>
17
9
  );
18
- VisibilityIcon.displayName = 'VisibilityIcon';
19
10
 
20
11
  VisibilityIcon.propTypes = {
21
- color: string,
22
12
  size: number
23
13
  };
24
14
 
25
15
  VisibilityIcon.defaultProps = {
26
- color: '#000',
27
16
  size: 40
28
17
  };
29
18
 
@@ -0,0 +1,5 @@
1
+ Visible example
2
+
3
+ ```js
4
+ <VisibleIcon />
5
+ ```
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { number } from 'prop-types';
3
+ import IconBase from 'react-icon-base';
4
+
5
+ const VisibleIcon = props => (
6
+ <IconBase viewBox="0 0 32 32" {...props}>
7
+ <path d="M29.769 15.36C29.519 15.06 23.562 8 16 8S2.481 15.06 2.231 15.36a1 1 0 000 1.28C2.481 16.94 8.438 24 16 24s13.519-7.06 13.769-7.36a1 1 0 000-1.28zM16 22c-5.372 0-10.05-4.336-11.647-6 1.028-1.07 3.33-3.243 6.269-4.66a6 6 0 1010.757 0c2.939 1.416 5.24 3.59 6.268 4.66-1.598 1.665-6.275 6-11.647 6z" />
8
+ </IconBase>
9
+ );
10
+
11
+ VisibleIcon.propTypes = {
12
+ size: number
13
+ };
14
+
15
+ VisibleIcon.defaultProps = {
16
+ size: 40
17
+ };
18
+
19
+ export default VisibleIcon;
@@ -3,6 +3,7 @@ import spacing from 'constants/spacing';
3
3
 
4
4
  const ModalBody = styled.div`
5
5
  padding: ${props => (props.noPadding ? '0px' : spacing.s2)};
6
+ overflow-y: auto;
6
7
  `;
7
8
  ModalBody.displayName = 'ModalBody';
8
9
 
@@ -34,6 +34,8 @@ const Background = styled.div`
34
34
  `;
35
35
 
36
36
  const ModalContainer = styled.div`
37
+ display: flex;
38
+ flex-direction: column;
37
39
  background: white;
38
40
  position: relative;
39
41
  width: ${props => props.width};
@@ -43,7 +45,6 @@ const ModalContainer = styled.div`
43
45
  border-radius: ${vars.borderRadius};
44
46
  max-height: 90%;
45
47
  overflow-x: hidden;
46
- overflow-y: auto;
47
48
  ${props => props.version === '1' && '-webkit-overflow-scrolling: touch'};
48
49
 
49
50
  ${props =>
@@ -133,7 +133,6 @@ describe('<Modal />', () => {
133
133
  const modalContainer = wrapper.getByRole('region');
134
134
 
135
135
  expect(modalContainer).toHaveStyleRule('overflow-x', 'hidden');
136
- expect(modalContainer).toHaveStyleRule('overflow-y', 'auto');
137
136
 
138
137
  wrapper.rerender(
139
138
  <Modal close={closeFn} allowOverflow>
@@ -15,7 +15,7 @@ describe('<ResponsiveTabs />', () => {
15
15
  </ResponsiveTabs>
16
16
  );
17
17
 
18
- expect(getByRole('listbox')).toBeInTheDocument();
18
+ expect(getByRole('combobox')).toBeInTheDocument();
19
19
  expect(getAllByRole('option')).toHaveLength(2);
20
20
  });
21
21
 
@@ -38,7 +38,7 @@ describe('<ResponsiveTabs />', () => {
38
38
  expect(getByTestId('tab1')).toBeVisible();
39
39
  expect(getByTestId('tab2')).not.toBeVisible();
40
40
 
41
- const dropdown = getByRole('listbox');
41
+ const dropdown = getByRole('combobox');
42
42
  fireEvent.change(dropdown, { target: { value: 'Two' } });
43
43
 
44
44
  expect(getByTestId('tab1')).not.toBeVisible();
@@ -90,7 +90,7 @@ describe('<ResponsiveTabs />', () => {
90
90
  </ResponsiveTabs>
91
91
  );
92
92
 
93
- fireEvent.change(getByRole('listbox'), { target: { value: 'One' } });
93
+ fireEvent.change(getByRole('combobox'), { target: { value: 'One' } });
94
94
  expect(event).not.toHaveBeenCalled();
95
95
 
96
96
  fireEvent.click(getByRole('tab'));
@@ -118,6 +118,7 @@ const TimePicker = ({
118
118
  <>
119
119
  <MobileTimePicker
120
120
  type="time"
121
+ data-testid="mobileTimePicker"
121
122
  onChange={e => {
122
123
  const timeString = e.target.value;
123
124
  if (timeString.length === 5) {