@innovaccer/design-system 2.3.0 → 2.4.0-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 (87) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/core/components/atoms/backdrop/Backdrop.tsx +11 -1
  3. package/core/components/atoms/button/Button.tsx +60 -44
  4. package/core/components/atoms/button/__stories__/IconButtonGroup.story.tsx +4 -4
  5. package/core/components/atoms/button/__stories__/IconButtonSecondary.story.tsx +1 -1
  6. package/core/components/atoms/button/__tests__/Button.test.tsx +36 -1
  7. package/core/components/atoms/dropdown/DropdownList.tsx +1 -0
  8. package/core/components/atoms/dropdown/Loading.tsx +9 -9
  9. package/core/components/atoms/dropdown/__stories__/Options.tsx +2 -0
  10. package/core/components/atoms/dropdown/__tests__/Dropdown.test.tsx +12 -1
  11. package/core/components/atoms/dropdown/__tests__/Loading.test.tsx +66 -0
  12. package/core/components/atoms/dropdown/__tests__/Option.test.tsx +204 -0
  13. package/core/components/atoms/dropdown/option/CheckboxOption.tsx +1 -0
  14. package/core/components/atoms/dropdown/option/IconOption.tsx +3 -1
  15. package/core/components/atoms/dropdown/option/IconWithMetaOption.tsx +3 -1
  16. package/core/components/atoms/dropdown/option/index.tsx +7 -1
  17. package/core/components/molecules/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap +13 -0
  18. package/core/components/molecules/emptyState/__stories__/assets/pageNotLoaded.png +0 -0
  19. package/core/components/molecules/emptyState/__stories__/variants/noContentAvailable.story.tsx +26 -0
  20. package/core/components/molecules/emptyState/__stories__/variants/{smallSizeWithButton.story.tsx → noSearchResults.story.tsx} +2 -2
  21. package/core/components/molecules/emptyState/__stories__/variants/{largeSize.story.tsx → pageNotLoaded.story.tsx} +3 -3
  22. package/core/components/molecules/fileList/FileIcon.tsx +10 -2
  23. package/core/components/molecules/fileList/FileListItem.tsx +7 -3
  24. package/core/components/molecules/fileList/__stories__/__common__/fileListExample.tsx +1 -0
  25. package/core/components/molecules/fileList/__tests__/FileList.test.tsx +115 -0
  26. package/core/components/molecules/fileList/__tests__/__snapshots__/FileList.test.tsx.snap +232 -0
  27. package/core/components/molecules/inputMask/InputMask.tsx +2 -5
  28. package/core/components/molecules/inputMask/__tests__/InputMask.test.tsx +128 -0
  29. package/core/components/molecules/inputMask/__tests__/__snapshots__/InputMask.test.tsx.snap +39 -0
  30. package/core/components/molecules/modal/Modal.tsx +7 -5
  31. package/core/components/molecules/modal/__tests__/__snapshots__/Modal.test.tsx.snap +18 -0
  32. package/core/components/molecules/sidesheet/Sidesheet.tsx +5 -3
  33. package/core/components/molecules/sidesheet/__tests__/__snapshots__/Sidesheet.test.tsx.snap +2 -0
  34. package/core/components/organisms/calendar/Calendar.tsx +66 -22
  35. package/core/components/organisms/calendar/__stories__/variants/withEvents.story.tsx +45 -0
  36. package/core/components/organisms/calendar/__tests__/Calendar.test.tsx +10 -0
  37. package/core/components/organisms/calendar/__tests__/__snapshots__/Calendar.test.tsx.snap +1096 -1096
  38. package/core/components/organisms/calendar/config.ts +2 -2
  39. package/core/components/organisms/calendar/types.ts +1 -0
  40. package/core/components/organisms/datePicker/DatePicker.tsx +23 -9
  41. package/core/components/organisms/datePicker/__tests__/{DatePicker.tsx → DatePicker.test.tsx} +16 -1
  42. package/core/components/organisms/datePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +2257 -0
  43. package/core/components/organisms/dateRangePicker/__tests__/__snapshots__/DateRangePicker.test.tsx.snap +2552 -2550
  44. package/core/components/organisms/inlineMessage/InlineMessage.tsx +75 -0
  45. package/core/components/organisms/inlineMessage/__stories__/Default.story.tsx +18 -0
  46. package/core/components/organisms/inlineMessage/__stories__/Error.story.tsx +19 -0
  47. package/core/components/organisms/inlineMessage/__stories__/Info.story.tsx +19 -0
  48. package/core/components/organisms/inlineMessage/__stories__/Success.story.tsx +19 -0
  49. package/core/components/organisms/inlineMessage/__stories__/Warning.story.tsx +18 -0
  50. package/core/components/organisms/inlineMessage/__stories__/variants/InlineMessageWithinTable.story.tsx +139 -0
  51. package/core/components/organisms/inlineMessage/__tests__/InlineMessage.test.tsx +91 -0
  52. package/core/components/organisms/inlineMessage/__tests__/__snapshots__/InlineMessage.test.tsx.snap +139 -0
  53. package/core/components/organisms/inlineMessage/index.tsx +1 -0
  54. package/core/components/organisms/timePicker/__tests__/__snapshots__/TimePicker.test.tsx.snap +8 -0
  55. package/core/index.tsx +2 -0
  56. package/core/index.type.tsx +1 -0
  57. package/core/utils/__tests__/__snapshots__/TS.test.tsx.snap +485 -466
  58. package/css/dist/index.css +72 -8
  59. package/css/dist/index.css.map +1 -1
  60. package/css/src/components/calendar.css +37 -5
  61. package/css/src/components/card.css +1 -1
  62. package/css/src/components/chipInput.css +2 -2
  63. package/css/src/components/editableChipInput.css +2 -1
  64. package/css/src/components/inlineMessage.css +29 -0
  65. package/dist/core/components/atoms/backdrop/Backdrop.d.ts +1 -0
  66. package/dist/core/components/atoms/button/Button.d.ts +1 -0
  67. package/dist/core/components/atoms/popperWrapper/PopperWrapper.d.ts +28 -27
  68. package/dist/core/components/organisms/calendar/Calendar.d.ts +6 -1
  69. package/dist/core/components/organisms/calendar/types.d.ts +3 -0
  70. package/dist/core/components/organisms/inlineMessage/InlineMessage.d.ts +15 -0
  71. package/dist/core/components/organisms/inlineMessage/index.d.ts +1 -0
  72. package/dist/core/index.d.ts +1 -0
  73. package/dist/core/index.type.d.ts +1 -0
  74. package/dist/index.esm.js +189 -66
  75. package/dist/index.js +201 -80
  76. package/dist/index.js.map +1 -1
  77. package/dist/index.umd.js +1 -1
  78. package/dist/index.umd.js.br +0 -0
  79. package/dist/index.umd.js.gz +0 -0
  80. package/dts.config.js +13 -0
  81. package/package.json +4 -2
  82. package/types/innovaccer-design-system/index.d.ts +39 -0
  83. package/types/innovaccer-design-system/innovaccer-design-system-tests.ts +0 -0
  84. package/types/innovaccer-design-system/tsconfig.json +23 -0
  85. package/types/innovaccer-design-system/tslint.json +1 -0
  86. package/core/components/molecules/emptyState/__stories__/variants/smallSizeWithoutButton.story.tsx +0 -21
  87. package/core/components/organisms/datePicker/__tests__/__snapshots__/DatePicker.tsx.snap +0 -2164
@@ -0,0 +1,128 @@
1
+ import * as React from 'react';
2
+ import { render, fireEvent } from '@testing-library/react';
3
+ import { InputMaskProps as Props } from '@/index.type';
4
+ import { InputMask } from '@/index';
5
+ import { testHelper, filterUndefined, valueHelper, testMessageHelper } from '@/utils/testHelper';
6
+ const onFocusHandler = jest.fn();
7
+ const onChangeHandler = jest.fn();
8
+ const onBlurHandler = jest.fn();
9
+ const onClearHandler = jest.fn();
10
+
11
+ const mask = [
12
+ /\d/,
13
+ /\d/,
14
+ /\d/,
15
+ /\d/,
16
+ ' ',
17
+ /\d/,
18
+ /\d/,
19
+ /\d/,
20
+ /\d/,
21
+ ' ',
22
+ /\d/,
23
+ /\d/,
24
+ /\d/,
25
+ /\d/,
26
+ ' ',
27
+ /\d/,
28
+ /\d/,
29
+ /\d/,
30
+ /\d/,
31
+ ];
32
+
33
+ describe('Input Mask component', () => {
34
+ const mapper = {
35
+ placeholderChar: valueHelper('*', { required: false }),
36
+ mask: valueHelper(mask, { required: true }),
37
+ caption: valueHelper('card', { required: true }),
38
+ validators: valueHelper(undefined, { required: true }),
39
+ onChange: valueHelper(onChangeHandler, { required: false }),
40
+ onBlur: valueHelper(onBlurHandler, { required: false }),
41
+ onClear: valueHelper(onChangeHandler, { required: false }),
42
+ };
43
+
44
+ const testFunc = (props: Record<string, any>): void => {
45
+ const attr = filterUndefined(props) as Props;
46
+ it(testMessageHelper(attr), () => {
47
+ const { baseElement } = render(<InputMask {...attr} />);
48
+ expect(baseElement).toMatchSnapshot();
49
+ });
50
+ };
51
+ testHelper(mapper, testFunc);
52
+ });
53
+
54
+ describe('Input Mask component with prop mask', () => {
55
+ it('render Input', () => {
56
+ const { getByTestId } = render(<InputMask mask={mask} />);
57
+ expect(getByTestId('DesignSystem-InputMask--Wrapper')).toHaveClass('d-flex');
58
+ });
59
+ });
60
+
61
+ describe('Input Mask component prop: onFocusHandler', () => {
62
+ it('calls onFocusHandler callback without value', () => {
63
+ const { getByTestId } = render(<InputMask mask={mask} onFocus={onFocusHandler} />);
64
+ const input = getByTestId('DesignSystem-Input');
65
+ fireEvent.focus(input);
66
+ expect(input).toHaveAttribute('value', '____ ____ ____ ____');
67
+ expect(onFocusHandler).toHaveBeenCalledTimes(1);
68
+ });
69
+
70
+ it('calls onFocusHandler callback with value', () => {
71
+ const value = '1111 2222 3333 4444';
72
+ const { getByTestId } = render(<InputMask mask={mask} onFocus={onFocusHandler} value={value} />);
73
+ const input = getByTestId('DesignSystem-Input');
74
+ fireEvent.focus(input);
75
+ expect(input).toHaveAttribute('value', value);
76
+ });
77
+ });
78
+
79
+ describe('Input Mask component prop: onBlurHandler', () => {
80
+ const value = '____ ____ ____ ____';
81
+ it('calls onBlurHandler callback when clearOnEmptyBlur is false', () => {
82
+ const { getByTestId } = render(<InputMask mask={mask} onBlur={onBlurHandler} clearOnEmptyBlur={false} />);
83
+ const input = getByTestId('DesignSystem-Input');
84
+ fireEvent.focus(input);
85
+ expect(input).toHaveValue(value);
86
+ fireEvent.blur(input);
87
+ expect(input).toHaveValue(value);
88
+ });
89
+
90
+ it('calls onBlurHandler callback when clearOnEmptyBlur is true', () => {
91
+ const { getByTestId } = render(<InputMask mask={mask} onBlur={onBlurHandler} />);
92
+ const input = getByTestId('DesignSystem-Input');
93
+ fireEvent.focus(input);
94
+ expect(input).toHaveValue(value);
95
+ fireEvent.blur(input);
96
+ expect(input).toHaveValue('');
97
+ });
98
+ });
99
+
100
+ describe('Input Mask component prop: onChangeHandler', () => {
101
+ it('calls onChangeHandler callback ', async () => {
102
+ const value = '33';
103
+ const { getByTestId } = render(<InputMask mask={mask} onChange={onChangeHandler} />);
104
+ const input = getByTestId('DesignSystem-Input');
105
+ input.focus();
106
+ fireEvent.select(input, {
107
+ target: { selectionStart: 0, selectionEnd: 0 },
108
+ });
109
+ fireEvent.change(input, {
110
+ target: {
111
+ value,
112
+ selectionStart: value.length,
113
+ selectionEnd: value.length,
114
+ },
115
+ });
116
+ expect(onChangeHandler).toHaveBeenCalled();
117
+ });
118
+ });
119
+
120
+ describe('Input Mask component prop: onClearHandler', () => {
121
+ it('calls onClearHandler callback without value', () => {
122
+ const value = '1111 2222 3333 4444';
123
+ const { getByTestId } = render(<InputMask mask={mask} onClear={onClearHandler} value={value} />);
124
+ const input = getByTestId('DesignSystem-Input--closeIcon');
125
+ fireEvent.click(input);
126
+ expect(onClearHandler).toHaveBeenCalledTimes(1);
127
+ });
128
+ });
@@ -0,0 +1,39 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Input Mask component
4
+ mask: [{},{},{},{}," ",{},{},{},{}," ",{},{},{},{}," ",{},{},{},{}], caption: "card", placeholderChar: [null,"*"], onChange: [null], onBlur: [null], onClear: [null]
5
+ 1`] = `
6
+ <body>
7
+ <div>
8
+ <div
9
+ class="d-flex flex-column flex-grow-1"
10
+ data-test="DesignSystem-InputMask--Wrapper"
11
+ >
12
+ <div
13
+ class="Input Input--regular"
14
+ data-test="DesignSystem-InputWrapper"
15
+ style="min-width: 256px;"
16
+ >
17
+ <input
18
+ autocomplete="off"
19
+ class="Input-input Input-input--regular"
20
+ data-test="DesignSystem-Input"
21
+ type="text"
22
+ value=""
23
+ />
24
+ </div>
25
+ <div
26
+ class="Caption Caption--withInput"
27
+ data-test="DesignSystem-Caption"
28
+ >
29
+ <span
30
+ class="Text Text--subtle Text--medium Text--small"
31
+ data-test="DesignSystem-Text"
32
+ >
33
+ card
34
+ </span>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </body>
39
+ `;
@@ -223,6 +223,8 @@ class Modal extends React.Component<ModalProps, ModalState> {
223
223
  onClose,
224
224
  } = this.props;
225
225
 
226
+ const BackdropZIndex: number = zIndex ? zIndex - 1 : 1000;
227
+
226
228
  const classes = classNames(
227
229
  {
228
230
  Modal: true,
@@ -311,8 +313,8 @@ class Modal extends React.Component<ModalProps, ModalState> {
311
313
  {headerOptions || footerOptions || footer || header ? (
312
314
  <OverlayBody className={bodyClass}>{this.props.children}</OverlayBody>
313
315
  ) : (
314
- children
315
- )}
316
+ children
317
+ )}
316
318
  </>
317
319
  )}
318
320
  {(!!footer || !!footerOptions) && (
@@ -334,15 +336,15 @@ class Modal extends React.Component<ModalProps, ModalState> {
334
336
  {ModalContainer}
335
337
  </OutsideClick>
336
338
  ) : (
337
- ModalContainer
338
- );
339
+ ModalContainer
340
+ );
339
341
 
340
342
  const WrapperElement = ReactDOM.createPortal(ModalWrapper, this.element);
341
343
 
342
344
  return (
343
345
  <>
344
346
  {WrapperElement}
345
- <Backdrop open={this.state.animate} />
347
+ <Backdrop open={this.state.animate} zIndex={BackdropZIndex} />
346
348
  </>
347
349
  );
348
350
  }
@@ -78,6 +78,7 @@ exports[`Modal component
78
78
  class="Backdrop Backdrop--open Backdrop-animation--open"
79
79
  data-layer="true"
80
80
  data-test="DesignSystem-Backdrop"
81
+ style="z-index: 1000;"
81
82
  />
82
83
  </body>
83
84
  `;
@@ -165,6 +166,7 @@ exports[`Modal component
165
166
  class="Backdrop Backdrop--open Backdrop-animation--open"
166
167
  data-layer="true"
167
168
  data-test="DesignSystem-Backdrop"
169
+ style="z-index: 1000;"
168
170
  />
169
171
  </body>
170
172
  `;
@@ -308,6 +310,7 @@ exports[`Modal component
308
310
  class="Backdrop Backdrop--open Backdrop-animation--open"
309
311
  data-layer="true"
310
312
  data-test="DesignSystem-Backdrop"
313
+ style="z-index: 1000;"
311
314
  />
312
315
  </body>
313
316
  `;
@@ -456,6 +459,7 @@ exports[`Modal component
456
459
  class="Backdrop Backdrop--open Backdrop-animation--open"
457
460
  data-layer="true"
458
461
  data-test="DesignSystem-Backdrop"
462
+ style="z-index: 1000;"
459
463
  />
460
464
  </body>
461
465
  `;
@@ -599,6 +603,7 @@ exports[`Modal component
599
603
  class="Backdrop Backdrop--open Backdrop-animation--open"
600
604
  data-layer="true"
601
605
  data-test="DesignSystem-Backdrop"
606
+ style="z-index: 1000;"
602
607
  />
603
608
  </body>
604
609
  `;
@@ -747,6 +752,7 @@ exports[`Modal component
747
752
  class="Backdrop Backdrop--open Backdrop-animation--open"
748
753
  data-layer="true"
749
754
  data-test="DesignSystem-Backdrop"
755
+ style="z-index: 1000;"
750
756
  />
751
757
  </body>
752
758
  `;
@@ -829,6 +835,7 @@ exports[`Modal component
829
835
  class="Backdrop Backdrop--open Backdrop-animation--open"
830
836
  data-layer="true"
831
837
  data-test="DesignSystem-Backdrop"
838
+ style="z-index: 1000;"
832
839
  />
833
840
  </body>
834
841
  `;
@@ -916,6 +923,7 @@ exports[`Modal component
916
923
  class="Backdrop Backdrop--open Backdrop-animation--open"
917
924
  data-layer="true"
918
925
  data-test="DesignSystem-Backdrop"
926
+ style="z-index: 1000;"
919
927
  />
920
928
  </body>
921
929
  `;
@@ -1059,6 +1067,7 @@ exports[`Modal component
1059
1067
  class="Backdrop Backdrop--open Backdrop-animation--open"
1060
1068
  data-layer="true"
1061
1069
  data-test="DesignSystem-Backdrop"
1070
+ style="z-index: 1000;"
1062
1071
  />
1063
1072
  </body>
1064
1073
  `;
@@ -1207,6 +1216,7 @@ exports[`Modal component
1207
1216
  class="Backdrop Backdrop--open Backdrop-animation--open"
1208
1217
  data-layer="true"
1209
1218
  data-test="DesignSystem-Backdrop"
1219
+ style="z-index: 1000;"
1210
1220
  />
1211
1221
  </body>
1212
1222
  `;
@@ -1350,6 +1360,7 @@ exports[`Modal component
1350
1360
  class="Backdrop Backdrop--open Backdrop-animation--open"
1351
1361
  data-layer="true"
1352
1362
  data-test="DesignSystem-Backdrop"
1363
+ style="z-index: 1000;"
1353
1364
  />
1354
1365
  </body>
1355
1366
  `;
@@ -1498,6 +1509,7 @@ exports[`Modal component
1498
1509
  class="Backdrop Backdrop--open Backdrop-animation--open"
1499
1510
  data-layer="true"
1500
1511
  data-test="DesignSystem-Backdrop"
1512
+ style="z-index: 1000;"
1501
1513
  />
1502
1514
  </body>
1503
1515
  `;
@@ -1580,6 +1592,7 @@ exports[`Modal component
1580
1592
  class="Backdrop Backdrop--open Backdrop-animation--open"
1581
1593
  data-layer="true"
1582
1594
  data-test="DesignSystem-Backdrop"
1595
+ style="z-index: 1000;"
1583
1596
  />
1584
1597
  </body>
1585
1598
  `;
@@ -1667,6 +1680,7 @@ exports[`Modal component
1667
1680
  class="Backdrop Backdrop--open Backdrop-animation--open"
1668
1681
  data-layer="true"
1669
1682
  data-test="DesignSystem-Backdrop"
1683
+ style="z-index: 1000;"
1670
1684
  />
1671
1685
  </body>
1672
1686
  `;
@@ -1810,6 +1824,7 @@ exports[`Modal component
1810
1824
  class="Backdrop Backdrop--open Backdrop-animation--open"
1811
1825
  data-layer="true"
1812
1826
  data-test="DesignSystem-Backdrop"
1827
+ style="z-index: 1000;"
1813
1828
  />
1814
1829
  </body>
1815
1830
  `;
@@ -1958,6 +1973,7 @@ exports[`Modal component
1958
1973
  class="Backdrop Backdrop--open Backdrop-animation--open"
1959
1974
  data-layer="true"
1960
1975
  data-test="DesignSystem-Backdrop"
1976
+ style="z-index: 1000;"
1961
1977
  />
1962
1978
  </body>
1963
1979
  `;
@@ -2101,6 +2117,7 @@ exports[`Modal component
2101
2117
  class="Backdrop Backdrop--open Backdrop-animation--open"
2102
2118
  data-layer="true"
2103
2119
  data-test="DesignSystem-Backdrop"
2120
+ style="z-index: 1000;"
2104
2121
  />
2105
2122
  </body>
2106
2123
  `;
@@ -2249,6 +2266,7 @@ exports[`Modal component
2249
2266
  class="Backdrop Backdrop--open Backdrop-animation--open"
2250
2267
  data-layer="true"
2251
2268
  data-test="DesignSystem-Backdrop"
2269
+ style="z-index: 1000;"
2252
2270
  />
2253
2271
  </body>
2254
2272
  `;
@@ -217,6 +217,8 @@ class Sidesheet extends React.Component<SidesheetProps, SidesheetState> {
217
217
  onClose,
218
218
  } = this.props;
219
219
 
220
+ const BackdropZIndex: number = zIndex ? zIndex - 1 : 1000;
221
+
220
222
  const classes = classNames(
221
223
  {
222
224
  Sidesheet: true,
@@ -298,15 +300,15 @@ class Sidesheet extends React.Component<SidesheetProps, SidesheetState> {
298
300
  {SidesheetContainer}
299
301
  </OutsideClick>
300
302
  ) : (
301
- SidesheetContainer
302
- );
303
+ SidesheetContainer
304
+ );
303
305
 
304
306
  const WrapperElement = ReactDOM.createPortal(SidesheetWrapper, this.element);
305
307
 
306
308
  return (
307
309
  <>
308
310
  {WrapperElement}
309
- <Backdrop open={this.state.animate} />
311
+ <Backdrop open={this.state.animate} zIndex={BackdropZIndex} />
310
312
  </>
311
313
  );
312
314
  }
@@ -82,6 +82,7 @@ exports[`Sidesheet component
82
82
  class="Backdrop Backdrop--open Backdrop-animation--open"
83
83
  data-layer="true"
84
84
  data-test="DesignSystem-Backdrop"
85
+ style="z-index: 1000;"
85
86
  />
86
87
  </body>
87
88
  `;
@@ -168,6 +169,7 @@ exports[`Sidesheet component
168
169
  class="Backdrop Backdrop--open Backdrop-animation--open"
169
170
  data-layer="true"
170
171
  data-test="DesignSystem-Backdrop"
172
+ style="z-index: 1000;"
171
173
  />
172
174
  </body>
173
175
  `;
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import classNames from 'classnames';
3
- import { Button, Heading, Subheading, Text } from '@/index';
3
+ import { Button, Heading, Text } from '@/index';
4
4
  import { BaseProps, extractBaseProps } from '@/utils/types';
5
5
 
6
6
  import config from './config';
7
- import { Size, Day, View } from './types';
7
+ import { Size, Day, View, Events } from './types';
8
8
  import {
9
9
  compareDate,
10
10
  compareYearBlock,
@@ -95,6 +95,13 @@ export type CalendarProps = {
95
95
  * **set `0` or `undefined` for infinite limit**
96
96
  */
97
97
  rangeLimit?: number;
98
+ /**
99
+ * Adds event highlighter to given date
100
+ * `events: {
101
+ * 'mm/dd/yyyy': true
102
+ * }`
103
+ */
104
+ events?: Events;
98
105
  } & SharedProps;
99
106
 
100
107
  interface CalendarState {
@@ -109,6 +116,9 @@ interface CalendarState {
109
116
  yearBlockNav: number;
110
117
  yearNav: number;
111
118
  monthNav: number;
119
+ todayDate: number;
120
+ currMonth: number;
121
+ currYear: number;
112
122
  }
113
123
 
114
124
  export class Calendar extends React.Component<CalendarProps, CalendarState> {
@@ -130,7 +140,7 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
130
140
  const yearNav = props.yearNav !== undefined ? props.yearNav : getDateInfo(currDate || Date.now()).year;
131
141
  const monthNav = props.monthNav !== undefined ? props.monthNav : getDateInfo(currDate || Date.now()).month;
132
142
  const { year, month, date } = getDateInfo(currDate);
133
-
143
+ const todayCompleteDate = getDateInfo(new Date());
134
144
  this.state = {
135
145
  currDate,
136
146
  startDate,
@@ -140,6 +150,9 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
140
150
  year,
141
151
  month,
142
152
  date,
153
+ todayDate: todayCompleteDate.date,
154
+ currMonth: todayCompleteDate.month,
155
+ currYear: todayCompleteDate.year,
143
156
  view: monthsInView > 1 ? 'date' : view,
144
157
  yearBlockNav: getYearBlock(yearNav),
145
158
  };
@@ -427,7 +440,7 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
427
440
  <Button
428
441
  type="button"
429
442
  className={headerIconClass}
430
- appearance="transparent"
443
+ appearance="basic"
431
444
  icon={`arrow_${type === 'next' ? 'forward' : 'back'}`}
432
445
  disabled={disabled}
433
446
  onClick={this.onNavIconClickHandler(type)}
@@ -600,6 +613,8 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
600
613
 
601
614
  const { size, firstDayOfWeek } = this.props;
602
615
 
616
+ const textSize = size === 'large' ? 'regular' : 'small';
617
+
603
618
  return (
604
619
  <>
605
620
  <div className="Calendar-dayValues">
@@ -610,9 +625,9 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
610
625
  const dayValue = (day + daysInRow + getIndexOfDay(firstDayOfWeek)) % daysInRow;
611
626
 
612
627
  return (
613
- <Subheading key={day} className={valueClass} appearance="disabled">
628
+ <Text key={day} className={valueClass} appearance="default" weight="strong" size={textSize}>
614
629
  {days[size][dayValue]}
615
- </Subheading>
630
+ </Text>
616
631
  );
617
632
  })}
618
633
  </div>
@@ -623,12 +638,31 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
623
638
  );
624
639
  };
625
640
 
641
+ renderEventsIndicator(size: string, active: boolean) {
642
+ const eventsIndicatorClass = classNames({
643
+ 'Calendar-eventsIndicator': true,
644
+ [`Calendar-eventsIndicator--${size}`]: true,
645
+ 'Calendar-eventsIndicator--active': active,
646
+ });
647
+ return <span data-test="DesignSystem-Calendar-Event-Indicator" className={eventsIndicatorClass} />;
648
+ }
649
+
626
650
  renderDateValues = (index: number) => {
627
651
  const { daysInRow } = config;
628
652
 
629
653
  const { size, rangePicker, firstDayOfWeek, disabledBefore, disabledAfter } = this.props;
630
654
 
631
- const { startDate, endDate, hoverDate, year: yearState, month: monthState, date: dateState } = this.state;
655
+ const {
656
+ startDate,
657
+ endDate,
658
+ hoverDate,
659
+ year: yearState,
660
+ month: monthState,
661
+ date: dateState,
662
+ currMonth,
663
+ currYear,
664
+ todayDate,
665
+ } = this.state;
632
666
 
633
667
  const { year: yearNavVal, month: monthNavVal } = this.getNavDateInfo(index);
634
668
 
@@ -638,6 +672,8 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
638
672
  const noOfRows = Math.ceil((dayRange + dummyDays) / daysInRow);
639
673
  const inRangeError = this.getInRangeError();
640
674
 
675
+ const events = this.props.events;
676
+
641
677
  const onClickHandler = (date: number) => () => {
642
678
  if (rangePicker) {
643
679
  if (startDate && endDate) {
@@ -672,6 +708,8 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
672
708
  (compareDate(disabledBefore, 'more', yearNavVal, monthNavVal, date) ||
673
709
  compareDate(disabledAfter, 'less', yearNavVal, monthNavVal, date));
674
710
  let active = !disabled && yearState === yearNavVal && monthState === monthNavVal && dateState === date;
711
+ const today =
712
+ !rangePicker && !disabled && currYear === yearNavVal && currMonth === monthNavVal && todayDate === date;
675
713
  let startActive = false;
676
714
  let endActive = false;
677
715
  let inRange = false;
@@ -707,6 +745,12 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
707
745
  endActive || (startDate && inRangeLast && compareDate(hoverDate, 'more', sYear, sMonth, sDate));
708
746
  const isRangeError = inRange && inRangeError;
709
747
 
748
+ const monthInString = `${monthNavVal + 1 > 9 ? monthNavVal + 1 : `0${monthNavVal + 1}`}`;
749
+ const dateInString = `${date > 9 ? date : `0${date}`}`;
750
+ const yearInString = `${yearNavVal}`;
751
+ const completeDateString = `${monthInString}/${dateInString}/${yearInString}`;
752
+ const isEventExist = events && typeof events === 'object' && events.hasOwnProperty(completeDateString);
753
+
710
754
  const wrapperClass = classNames({
711
755
  'Calendar-valueWrapper': true,
712
756
  'Calendar-valueWrapper--inRange': inRange || (rangePicker && active),
@@ -729,24 +773,24 @@ export class Calendar extends React.Component<CalendarProps, CalendarState> {
729
773
  'Calendar-value--disabled': disabled,
730
774
  'Calendar-dateValue': true,
731
775
  [`Calendar-dateValue--${size}`]: size,
776
+ 'Calendar-value--currentDate': today,
732
777
  });
733
778
  return (
734
- <div
735
- key={`${row}-${col}`}
736
- className={wrapperClass}
737
- data-test="designSystem-Calendar-WrapperClass"
738
- >
779
+ <div key={`${row}-${col}`} className={wrapperClass} data-test="designSystem-Calendar-WrapperClass">
739
780
  {!dummy && (
740
- <Text
741
- appearance={active ? 'white' : disabled ? 'disabled' : 'default'}
742
- size={size === 'small' ? 'small' : 'regular'}
743
- data-test="DesignSystem-Calendar--dateValue"
744
- className={valueClass}
745
- onClick={onClickHandler(date)}
746
- onMouseOver={onMouseOverHandler(date)}
747
- >
748
- {date}
749
- </Text>
781
+ <>
782
+ <Text
783
+ appearance={active ? 'white' : disabled ? 'disabled' : today ? 'link' : 'default'}
784
+ size={size === 'small' ? 'small' : 'regular'}
785
+ data-test="DesignSystem-Calendar--dateValue"
786
+ className={valueClass}
787
+ onClick={onClickHandler(date)}
788
+ onMouseOver={onMouseOverHandler(date)}
789
+ >
790
+ {date}
791
+ </Text>
792
+ {isEventExist && this.renderEventsIndicator(size, active)}
793
+ </>
750
794
  )}
751
795
  </div>
752
796
  );
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import Calendar from '../../Calendar';
3
+ import Card from '@/components/atoms/card';
4
+ import Heading from '@/components/atoms/heading';
5
+
6
+ // CSF format story
7
+ export const withEvents = () => {
8
+ return (
9
+ <>
10
+ <div className="mt-8">
11
+ <Heading>size: small with events</Heading>
12
+ <div className="d-flex">
13
+ <div className="mr-8">
14
+ <Card className="d-inline-flex" shadow="light">
15
+ <Calendar events={{ '12/21/2021': true }} date={new Date('12/21/2021')} size={'small'} />
16
+ </Card>
17
+ </div>
18
+ </div>
19
+ </div>
20
+
21
+ <div className="mt-8">
22
+ <Heading>size: large with events</Heading>
23
+ <div className="d-flex">
24
+ <div className="mr-8">
25
+ <Card className="d-inline-flex" shadow="light">
26
+ <Calendar events={{ '12/20/2021': true }} date={new Date('12/21/2021')} size={'large'} />
27
+ </Card>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </>
32
+ );
33
+ };
34
+
35
+ export default {
36
+ title: 'Components/Calendar/Variants/With Events',
37
+ component: Calendar,
38
+ parameters: {
39
+ docs: {
40
+ docPage: {
41
+ title: 'Calendar',
42
+ },
43
+ },
44
+ },
45
+ };
@@ -121,4 +121,14 @@ describe('Calendar compoennt', () => {
121
121
  expect(getByTestId('DesignSystem-Calendar')).toHaveClass('Calendar--large');
122
122
  expect(getAllByTestId('DesignSystem-Calendar--yearValue')[0]).toHaveClass('Calendar-yearValue--large');
123
123
  });
124
+
125
+ it('renders events indicator on given date', () => {
126
+ const events = { '09/12/2021': true };
127
+ const { getByTestId, getAllByTestId } = render(
128
+ <Calendar date={new Date('09/12/2021')} events={events} size="small" />
129
+ );
130
+
131
+ expect(getByTestId('DesignSystem-Calendar-Event-Indicator')).toBeInTheDocument();
132
+ expect(getAllByTestId('DesignSystem-Calendar-Event-Indicator')[0]).toHaveClass('Calendar-eventsIndicator--small');
133
+ });
124
134
  });